Skip to content
ArchiveZaunEkko Docs
Reading
Text size
Fonts
简体中文English
Show contents

Authentication and calls

Status
Current
Updated
2026-08-11
Scope
API Platform call surface

What you need

  1. A ZaunEkko Account;
  2. An API key — create one on the "API keys" page in Account;
  3. Enough points.

About API keys

A key looks like zek_live_..., is long-lived, and can be revoked at any time.

The plaintext is shown once, at creation. Only its digest is stored, so once you close the page it cannot be recovered. Put it straight into your secret manager or environment variables, and do not commit it to a repository.

A key can only call services. Reviewing, publishing, and managing a provider are all beyond it — those need you, in a browser. That is deliberate: a long-lived credential is exposed for far longer than a browser session, so it should be able to do less.

If a key leaks, revoke it in Account. Revocation cannot be undone; create a new key if you need to keep going.

Making a call

curl -X POST "https://api.zaunekko.com/v1/services/{serviceCode}/versions/{version}:invoke" \
  -H "Authorization: Bearer zek_live_..." \
  -H "Idempotency-Key: your-stable-unique-key" \
  -H "Content-Type: application/json" \
  -d '{ ...a body matching that version request schema }'

A browser session's access token also works, but it is short-lived and its refresh token rotates on every use, which makes it unsuitable for unattended scheduled jobs — a single failure to persist a rotated token silently breaks the integration. Use an API key for server-side work.

Idempotency-Key is required

The header cannot be empty and is at most 191 characters. Its job is to prevent double charging.

Network timeouts, dropped connections, client retries — in all of these you cannot tell whether the request arrived. Resend with the same key and the platform recognises it as the same call, returning the original result rather than spending a second time.

So the key must be:

One workable approach is to fold a business identifier and a time window into it, for example daily-ranking-2026-08-09.

The same key with a different request body is rejected, because that would mean the key's meaning had already been broken.

Checking your current call quota

Each Account has a quota for its current call window. You can check it before making a new call:

GET /v1/rate-limit
Authorization: Bearer zek_live_...

The response contains the current policy, the maximum accepted calls in limit, the window length in windowSeconds, the calls already accepted in accepted, the calls left in remaining, and the reset time in resetAt.

Quota is consumed only when the platform accepts a new call intent. Replaying an existing call with the same Idempotency-Key does not consume quota again; using a new key is treated as a new call.

When the window is exhausted, the call returns HTTP 429 with the stable error code RATE_LIMIT_EXCEEDED. The Retry-After response header gives the suggested wait in seconds, and the response body carries the current policy, limit, window, and retry delay:

{
  "code": "RATE_LIMIT_EXCEEDED",
  "message": "The current call window quota is exhausted; try again later",
  "policy": "api-human-level-v1",
  "limit": 5,
  "windowSeconds": 60,
  "retryAfter": 37
}

Wait for the duration in Retry-After before submitting a new call. If you are only resolving a call whose network outcome is unknown, retry with its original Idempotency-Key.

What callers do not see

Neither accepted in the request nor returned in the receipt: the provider's address, headers or credentials, the revenue split, or the identity of the parties involved.

These are not being withheld — they simply fall outside the caller's information boundary. What you need is whether the call succeeded, how many points it spent, and what result came back.

Receipts

GET /v1/invocations
GET /v1/invocations/{invocationId}

A receipt carries the call's state and what it actually spent. While settlement is still open, the receipt will not claim "no charge" — it says explicitly that the outcome is pending, rather than handing you a zero that might be wrong. After an approved full points refund completes, settlement is shown as REFUNDED, actual spend is zero, and the original listed price and refund time remain visible.

Disputes, refunds, and content reports

In Marketplace, you can open a dispute from the receipt for your own HUMAN call. You can also submit a content report from the currently public exact Publication page. Each submission uses its own Idempotency-Key, so a network retry does not create another case.

An approved call dispute can only return the full amount in platform points. Partial refunds and cash refunds are not supported. If a refund is temporarily blocked, the case keeps its state and decision evidence for later handling rather than claiming the points have arrived.

When a content report is upheld, the platform stops publicly listing the Listing and blocks new calls. This does not delete historical Publications, Invocations, receipts, or points records; only an explicit platform decision can release the hold. If another active hold still exists for that Listing, releasing one case does not restore it early.

You can track your cases under "Disputes & reports" in Marketplace. You only see cases you submitted, not the operator's account details or another user's identity.

Services that produce artifacts

Some services return media or other binary output alongside their JSON. For those, the response body does not contain the file itself, only an artifact manifest — one entry per artifact, each with an identifier and a content digest.

Download each one from the manifest:

GET /v1/invocations/{invocationId}/artifacts/{artifactId}
Authorization: Bearer zek_live_...

Only the account that made the call can download its artifacts, and the call must already be settled.

The platform reads the object in full and re-checks it against the digest before writing anything out, so partial downloads are not supported (a Range header is rejected) — an artifact is an immutable object, and a partial read cannot be verified.

Failure and retries

Under no circumstances does reusing the same Idempotency-Key cause a second charge.