Using the API

    Idempotency

    Send the same request twice and pay for it once.


    The problem

    Every metered call costs money. If the connection drops after you send a request, you cannot tell whether it ran. Sending it again might charge you a second time; not sending it might leave you without an answer.

    The fix

    Add an Idempotency-Key header with a value you generate, such as a UUID:

    bash
    curl https://api.zuse.live/v2/enrichments \
      -H "Authorization: Bearer $ZUSE_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: 7b1e0b0e-6f0a-4a5e-9a51-2f3a6b0c9d11" \
      -d '{ "license_id": 48211 }'

    The first request with a key runs normally. For the next 24 hours, the same key with the same request returns the stored answer:

    • The work does not run again.
    • Nothing is charged again.
    • The response carries Idempotent-Replayed: true. A replayed create answers 200 rather than 201.

    So a retry is always safe: reuse the key for the retry, and use a new key for a new request.

    Where it works

    CallIdempotency-Key
    POST /v2/enrichmentsSupported, and strongly recommended.
    GET /v2/professionals, /v2/practices, /v2/licensesSupported. Reads are harmless to repeat, but each is billed; the key stops a retry from being billed again.
    MCP enrich_personNot available. An MCP client cannot send the header.
    Free reference callsNot needed.

    Rules

    • A key is 1 to 128 printable characters. Use a UUID.
    • Keys belong to your account. Another account using the same string is unrelated.
    • Same key, different request returns 409 idempotency_key_reused. A key is tied to the exact request it was first sent with.
    • Same key while the first is still running returns 409 request_in_progress with Retry-After: 2. Wait and send it again; you will get the finished answer.
    • A failed request is not stored. If the first attempt ended in an error, nothing was charged, and the retry runs for real. That is what you want after a 502.
    • Stored answers are deleted after 24 hours. After that, the key is free to mean something new.

    In code

    python
    import uuid, requests
    
    def enrich(license_id, key=None):
        key = key or str(uuid.uuid4())          # one key per piece of work...
        for attempt in range(4):
            try:
                resp = requests.post(
                    f"{API}/enrichments",
                    headers={**HEADERS, "Idempotency-Key": key},   # ...reused on every retry
                    json={"license_id": license_id},
                    timeout=60,
                )
            except requests.RequestException:
                continue                         # no answer: safe to send again
            if resp.status_code in (409, 429, 502, 503, 504):
                time.sleep(float(resp.headers.get("Retry-After", 2 ** attempt)))
                continue
            resp.raise_for_status()
            return resp.json()
        raise RuntimeError("enrichment did not complete")