Skip to Content
APIMaking Requests

Making Requests

Every Scenema API request is a standard HTTPS call with a Bearer token in the Authorization header. This page covers the request shape, response format, and worked examples in the common languages.

Request shape

<METHOD> https://scenema.ai/api/service/<path> Authorization: Bearer sk_your_key Content-Type: application/json (for POST / PATCH / PUT) <optional JSON body>
  • Methods follow standard REST: GET for reads, POST for create, PATCH for partial update, DELETE for revoke.
  • Request bodies are JSON. If you send a POST or PATCH without Content-Type: application/json, the server treats the body as empty.
  • URL parameters are lowercase kebab-case. Path parameters are the raw resource id, no quoting.

Response shape

Every response is JSON. Success responses vary by endpoint but always parse into a stable shape documented alongside each endpoint. Error responses are consistent:

{ "error": "<human-readable message>", "code": "<optional machine-readable code>" }

Refer to Errors for the full status code and code list.

Worked example: list your API keys

This endpoint is the canonical smoke test. It requires only auth, returns quickly, and confirms your credentials are wired correctly before you move on to heavier calls.

curl

curl -H "Authorization: Bearer $SCENEMA_KEY" \ https://scenema.ai/api/service/user/api-keys

JavaScript (fetch)

const res = await fetch('https://scenema.ai/api/service/user/api-keys', { headers: { Authorization: `Bearer ${process.env.SCENEMA_KEY}` }, }); const body = await res.json(); console.log(body.keys);

Python (requests)

import os import requests resp = requests.get( 'https://scenema.ai/api/service/user/api-keys', headers={'Authorization': f"Bearer {os.environ['SCENEMA_KEY']}"}, ) resp.raise_for_status() print(resp.json()['keys'])

Go (net/http)

req, _ := http.NewRequest("GET", "https://scenema.ai/api/service/user/api-keys", nil) req.Header.Set("Authorization", "Bearer "+os.Getenv("SCENEMA_KEY")) resp, err := http.DefaultClient.Do(req)

Handling rate limits gracefully

Rate-limited responses return HTTP 429 Too Many Requests with a Retry-After header carrying the number of seconds until your window rolls. Any HTTP client that respects Retry-After (curl with --retry, most library retry adapters) will handle this without extra code.

Manual pattern:

async function callWithBackoff(url, opts, maxAttempts = 5) { for (let attempt = 0; attempt < maxAttempts; attempt++) { const res = await fetch(url, opts); if (res.status !== 429) return res; const retryAfter = Number(res.headers.get('retry-after') ?? '1'); await new Promise(r => setTimeout(r, retryAfter * 1000)); } throw new Error('Rate limit backoff exhausted'); }

See Rate Limits for the per-plan ceilings and the mechanics of Scenema’s fixed-window counter.

Idempotency

Read requests are always safe to retry. Mutation requests (create-a-key, revoke, disable) are idempotent by design: creating the same-named key twice produces two rows with distinct ids; revoking a key that is already gone returns 404; toggling enabled to a state it is already in is a no-op that returns 204. You can safely retry a request that failed with a network error or 5xx.

Timeouts and retries

Scenema’s HTTP path targets sub-100ms response for auth and management endpoints. Generation endpoints can take longer depending on the model. Set your client timeout accordingly:

  • Auth + management endpoints: 10 seconds is generous.
  • Generation endpoints: 60 seconds or longer depending on the media type. Consult the endpoint-specific docs for typical latency.

For retries on network-level errors, use exponential backoff starting at 500ms with a cap around 30 seconds. On 429 responses, always respect the Retry-After value instead of backing off blindly.

Last updated on