AI-CORE Gateway

integration guide

What this is

The AI-CORE API Gateway is the single public entry point to AI-CORE job services (metadata extraction, PDF anonymization, …). You authenticate with an API key, declare who is calling via identity headers, and submit jobs over plain HTTPS — either synchronously (for bounded tasks) or asynchronously with a callback webhook.

Interactive API reference: Swagger UI (try-it-out, Authorize button) · ReDoc (readable reference) · machine-readable OpenAPI schema.

Authentication

Every call to /api/v1/… requires three headers:

HeaderRequiredMeaning
X-Api-KeyyesThe API key issued by the gateway admin. 401 if missing, unknown, disabled or expired. Identifies your consumer system (baked into the key at issue time).
X-TenantyesTenant on whose behalf the call is made. 400 if missing. Job results are only visible to this tenant.
X-UseryesEnd user on whose behalf the call is made. 400 if missing.

Every identified call is recorded in the key's usage history (system, tenant, user, route, status, duration) — including denied attempts. Keys are issued per system with per-service permissions via the admin console (master key required) — ask the gateway administrator for one.

Quickstart

Synchronous call — metadata extraction

No callback_url: the response body is the service's native result (may take up to ~3 minutes).

curl -sS https://<gateway-host>/api/v1/metadata_extraction \
  --max-time 220 \
  -H "X-Api-Key: $API_KEY" \
  -H "X-Tenant: mytenant" -H "X-User: some.user" \
  -H "Content-Type: application/json" \
  -d '{
    "doc_reference": "https://example.org/documents/decreto.pdf",
    "document_kind": "auto",
    "max_pages": 10
  }'

Asynchronous call — PDF anonymization

callback_url set: you get 202 {"job_id"} at once; the result is POSTed to your webhook. (Omit it to poll instead — see fire-and-poll.)

curl -sS https://<gateway-host>/api/v1/pdf_anonymization \
  -H "X-Api-Key: $API_KEY" \
  -H "X-Tenant: mytenant" -H "X-User: some.user" \
  -H "Content-Type: application/json" \
  -d '{
    "doc_reference": "https://example.org/documents/referto.pdf",
    "callback_url": "https://mysystem.example.org/webhooks/aicore"
  }'

PDFs travel either by reference (doc_reference: a URL) or inline (doc_content: base64) — exactly one of the two must be set.

sync Sync-emulation flow

Available on bounded tasks only (currently metadata_extraction). Omit callback_url and the gateway parks your request while the job runs:

  1. 200 with the service's native response — the normal case, within the 180 s park budget.
  2. Business errors keep their original HTTP status (ResponseError body; job timeout → 504).
  3. If the budget expires (cold start, queue, long job) the call degrades to 202 {"job_id"} with a Location header → poll for the result.
Two rules for sync callers: set your HTTP client timeout above 200 s (the gateway parks up to 180 s; the platform chain is gateway 180 s < orchestrator 200 s < load-balancer idle 240 s), and always handle a 202 — under load a sync call can degrade to accepted-plus-poll instead of an inline result.

async Async + callback flow

Set callback_url (optional on every route) and the submit returns 202 {"job_id"} immediately. When the job reaches a terminal state, the platform POSTs this envelope to your webhook:

POST <callback_url>
Content-Type: application/json

{
  "job_id": "1f0c1e0a-7b6e-4b9e-9b1a-2a7c8d9e0f11",
  "service": "pdf-anonymization",
  "task": "pdf_anonymization",
  "status": "ok",                // "ok" | "error"
  "response": { ... },           // the service's native response when status=ok
  "error": null,                 // error message when status=error
  "error_code": null             // business HTTP status when status=error (e.g. 504 timeout)
}

No webhook? Fire-and-poll

Omitting callback_url works on every route. On long tasks (pdf_anonymization) the submit still answers 202 {"job_id"} immediately, with a Location header pointing at the poll endpoint. Mind the windows: the job stays pollable as pending while it runs, and the terminal result stays available for 600 s after completion — poll promptly, or prefer a callback for unattended integrations.

Polling

For jobs submitted without a callback (fire-and-poll, or a sync call that degraded to 202):

curl -sS https://<gateway-host>/api/v1/jobs/$JOB_ID/result \
  -H "X-Api-Key: $API_KEY" \
  -H "X-Tenant: mytenant" -H "X-User: some.user"
StatusMeaning
200Terminal result — same envelope as the callback (status is ok or error).
202Still pending — poll again (suggested interval: 2–5 s; for long jobs like pdf_anonymization, 5–15 s).
404Unknown job_id, or the result expired — it stays available 600 s after completion. Jobs submitted by another tenant also read as 404.
403Your key is not scoped for the polled job's task.

Idempotency & retries

Error model

Two body shapes, depending on which layer rejects the call:

ShapeProduced byStatuses
{"detail": "…"} Authentication / validation layer 401 bad key · 403 system mismatch or missing scope · 400 missing identity headers · 422 request body validation
{"code": int, "message": "…"} Job layer (ResponseError) 404 unknown/expired job · 502 job failed · 503 orchestrator disabled · 504 job timeout

Sync business errors propagate the service's own HTTP status (error_code parity with the callback envelope).

Permissions (scopes)

Keys carry a list of allowed services: ["*"] (all) or an explicit subset (e.g. ["metadata_extraction"]). Calling a route outside your key's scopes returns 403 "API key not authorized for service '…'". The jobs poll route checks the scope of the polled job's task.

Services

EndpointModeNotes
POST /api/v1/metadata_extraction sync or async Extracts structured metadata (title, dates, issuing body, act number, …) from the leading pages of a PDF. Bounded task (~2 min typical) → sync-emulation allowed. max_pages 1–30, taxonomy hint via document_kind, optional output language.
POST /api/v1/pdf_anonymization async — callback or poll Redacts personal data from a PDF (returns the anonymized PDF as base64 + stats). Jobs can run ~15 min, so the submit always answers 202: result via callback_url, or poll the Location header without one (result window 600 s). Options: custom category prompt, checksum-validated Italian fiscal-code/VAT detection, embedded-file handling, metadata scrubbing.
GET /api/v1/jobs/{job_id}/result Poll a parked job (see Polling).

Full request/response schemas with field-level docs and examples: Swagger UI · ReDoc.