Using the API

Common Patterns

Polling a run

Runs are asynchronous. After creating a run, poll its status until it reaches a terminal state (completed, failed, or stopped).

curl -s "https://api.extralt.com/runs/$RUN_ID" \
  -H "Authorization: Bearer $EXTRALT_API_KEY" | jq '.status'

A 10-second polling interval is a reasonable default. For long-running extractions, you can increase it to 30 seconds.

Handling errors

The API returns standard HTTP status codes. Wrap requests with error handling:

response = requests.post(
    f"{BASE_URL}/runs",
    headers=HEADERS,
    json={"robotId": robot_id, "urls": urls},
)

if response.status_code == 429:
    # Rate limited, wait and retry
    time.sleep(15)
    response = requests.post(
        f"{BASE_URL}/runs",
        headers=HEADERS,
        json={"robotId": robot_id, "urls": urls},
    )
elif response.status_code >= 400:
    error = response.json()
    print(f"Error: {error.get('message', 'Unknown error')}")
else:
    run = response.json()

See Error Codes for the complete error catalog.

Pagination

When listing captures, results may be paginated for large result sets. Use cursor-based pagination:

def get_all_captures(run_id):
    captures = []
    cursor = None

    while True:
        params = {"runId": run_id}
        if cursor:
            params["cursor"] = cursor

        response = requests.get(
            f"{BASE_URL}/captures", headers=HEADERS, params=params
        )
        data = response.json()
        captures.extend(data["items"])

        if not data.get("nextCursor"):
            break
        cursor = data["nextCursor"]

    return captures

Rate limit handling

The API allows approximately 120 requests per minute sustained, with a burst of 30 requests. When rate limited, you receive a 429 response.

The simplest strategy: wait 15 seconds to refill burst capacity, then retry.

import time

def api_request(method, url, **kwargs):
    response = requests.request(method, url, headers=HEADERS, **kwargs)
    if response.status_code == 429:
        time.sleep(15)
        response = requests.request(method, url, headers=HEADERS, **kwargs)
    return response

See Rate Limits for full details.

What's next