Quickstart

Your first extract in five minutes

The API does what the website does: you describe the data, we read public pages, you download rows. Three calls: create a job, poll it, download the file.

1. Get an API key

Create a free account, open your dashboard, and click Create API key. Copy the key right away: it starts with ue_live_ and is shown only once.

Keep it in an environment variable rather than in your code:

shell
export UE_API_KEY="ue_live_your_key_here"

2. Create a job

Send a prompt describing the rows and columns you want. Add up to 10 urls to stay on those pages, or leave them out and we look up public pages that match.

shell
curl -s -X POST https://137-23-46-77.sslip.io/v1/jobs \
  -H "Authorization: Bearer $UE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Book title, price, star rating, and availability",
    "urls": ["https://books.toscrape.com/"]
  }'

The job starts in the background. You get its id straight away:

202 Accepted
{
  "id": "6f1c2a4e-…",
  "status": "queued",
  "intent": "Retrieve book title, price, star rating, and availability",
  "fields": ["title", "price", "star_rating", "availability"],
  "urls": ["https://books.toscrape.com/"],
  "freeRemaining": 19
}

3. Poll until it’s done

Check every second or two. status moves through queued, analyzing, scraping, extracting, validating, and ends at completed or failed.

shell
curl -s https://137-23-46-77.sslip.io/v1/jobs/JOB_ID -H "Authorization: Bearer $UE_API_KEY"

4. Download the rows

shell
curl -s "https://137-23-46-77.sslip.io/v1/jobs/JOB_ID/download?format=csv" \
  -H "Authorization: Bearer $UE_API_KEY" -o books.csv
Results are deleted 30 minutes after the job completes. Download what you need before then.

All together in Node.js

extract.mjs
const API = "https://137-23-46-77.sslip.io";
const headers = {
  Authorization: `Bearer ${process.env.UE_API_KEY}`,
  "Content-Type": "application/json",
};

const created = await fetch(`${API}/v1/jobs`, {
  method: "POST",
  headers,
  body: JSON.stringify({
    prompt: "Book title, price, star rating, and availability",
    urls: ["https://books.toscrape.com/"],
  }),
});
if (!created.ok) throw new Error((await created.json()).error);
const { id } = await created.json();

let job;
do {
  await new Promise((r) => setTimeout(r, 1500));
  job = await fetch(`${API}/v1/jobs/${id}`, { headers }).then((r) => r.json());
} while (!["completed", "failed", "expired"].includes(job.status));

if (job.status !== "completed") throw new Error(job.error ?? job.status);
const file = await fetch(`${API}/v1/jobs/${id}/download?format=json`, { headers });
const { items } = await file.json();
console.log(`${items.length} rows`, items.slice(0, 3));

All together in Python

extract.py
import os, time, requests

API = "https://137-23-46-77.sslip.io"
headers = {"Authorization": f"Bearer {os.environ['UE_API_KEY']}"}

res = requests.post(f"{API}/v1/jobs", headers=headers, json={
    "prompt": "Book title, price, star rating, and availability",
    "urls": ["https://books.toscrape.com/"],
})
res.raise_for_status()
job_id = res.json()["id"]

while True:
    time.sleep(1.5)
    job = requests.get(f"{API}/v1/jobs/{job_id}", headers=headers).json()
    if job["status"] in ("completed", "failed", "expired"):
        break

if job["status"] != "completed":
    raise SystemExit(job.get("error") or job["status"])

rows = requests.get(f"{API}/v1/jobs/{job_id}/download",
                    params={"format": "json"}, headers=headers).json()["items"]
print(len(rows), "rows", rows[:3])

Next: keeping keys safe and the full endpoint reference.