Skip to main content
Rezolve Ai
API Reference

API Reference

Overview of the Rezolve Ai v1 API, authentication, scopes, jobs, and errors.

The v1 API covers the Contextual Enrichment Engine, product lookup, durable jobs, account usage, utilities, feeds, projects, partner tenants, ratings, and webhooks. Each endpoint has its own reference page in this section with parameters, schemas, request samples, and a live request panel. This page covers the parts that apply across all of them.

Base URL

https://ace.authoritas.com/api/v1

All paths below are relative to that base. For a machine readable description, GET /api/v1/openapi returns the full OpenAPI 3.0 spec.

Authentication

Every endpoint that requires auth accepts an API key in either header:

  • Authorization: Bearer <your-api-key>
  • X-API-Key: <your-api-key>

No key is needed for GET /api/v1/health or GET /api/v1/openapi. Create and manage keys under Settings, Developer console, Keys. See API Keys for details.

A partner account can also name the tenant a call is for with an X-Tenant-Id header, on any endpoint that takes an API key. See the Partner API guide.

One endpoint is not authenticated with an API key at all: POST /feeds/{id}/events is signed with the feed's own ingest secret. See the Feeds API guide.

Scopes

Each endpoint below checks for one scope. admin satisfies every check, and a write scope also satisfies the matching read check.

ScopeEndpoints that check it
enrichment:readGET /jobs, GET /jobs/{id}, GET /jobs/{id}/results, GET /usage, GET /enrichment/lookup, GET /enrichment/lookup/sources
enrichment:writePOST /enrichment/rules, POST /enrichment/content, POST /enrichment/pipeline, POST /enrichment/lookup, POST /jobs/{id}/cancel
utils:readPOST /utils/language, POST /utils/agentic-readiness, POST /utils/review-quality. These also accept enrichment:read or enrichment:write.
feeds:readGET /feeds, GET /feeds/{id}, GET /feeds/{id}/source, GET /feeds/{id}/delivery, GET /feeds/{id}/export, GET /feeds/{id}/enrichments
feeds:writePOST /feeds, DELETE /feeds/{id}, PUT /feeds/{id}/source, POST /feeds/{id}/source, PUT /feeds/{id}/delivery
webhooks:readGET /webhooks, GET /webhooks/{id}, GET /webhooks/{id}/deliveries
webhooks:writePOST /webhooks, PUT /webhooks/{id}, DELETE /webhooks/{id}
ratings:readGET /ratings/{productId}
ratings:writePOST /ratings/ingest
adminEvery v1 endpoint. Grants all other scopes. It is also the only scope that can create, rename, or delete a project: POST /projects, PUT /projects/{id}, DELETE /projects/{id}. On a partner account, an account-wide admin key is the one that manages tenants: every /tenants endpoint.

GET /projects and GET /projects/{id} accept any valid key, because they are how a caller finds the project ids the other endpoints ask for. A key pinned to a project sees only that project, and cannot create another.

The feeds, projects, and webhooks endpoints also accept a signed-in session, which is how the dashboard calls them. A session is not checked for scopes.

New keys get enrichment:read, enrichment:write, and utils:read by default. A call without the scope it needs returns 403 FORBIDDEN.

Endpoints

Enrichment: Health check, Generate contextual rules, Generate rules-grounded content, Run the full enrichment pipeline, Look up products by identifier, Look up one product, free, List the lookup sources you can use. See the Contextual Enrichment Engine and the product lookup guide.

Jobs: List enrichment jobs, Get a job, Get paginated job results, Cancel a job.

Account: Usage snapshot.

Utilities: Detect feed language, Score agentic readiness, Score review quality.

Feeds: List feeds, Create a feed, Get a feed, Delete a feed, Read a feed's source settings, Set a feed's source URL and schedule, Refresh now, or rotate the ingest secret, Push changed products, Read a feed's delivery settings, Publish a feed to channel URLs, Download a channel feed, Read generated content per field. See the Feeds API guide.

Projects: List projects, Create a project, Get a project, Update a project, Delete a project.

Tenants (partner accounts): List tenants, Create a tenant, Get a tenant, Update a tenant, Delete a tenant, List a tenant's keys, Create a tenant key, Revoke a tenant key, Rotate a tenant key, Get a tenant's usage. See the Partner API guide.

Ratings: Send customer ratings and reviews, Get resolved ratings for a product.

Webhooks: List webhook subscriptions, Create a webhook subscription, Get a webhook subscription, Update a webhook subscription, Delete a webhook subscription, List webhook deliveries. See the webhooks guide.

Content types

Use these values in the contentTypes array for POST /enrichment/content and POST /enrichment/pipeline.

Content typeAPI value
Product descriptionproduct-description
Meta tags and SEOmeta-tags
Enhanced JSON-LD schemajsonld-schema
IRL scenario cardsirl-scenarios
Internal linking recommendationsinternal-links
Product titleproduct-title
Highlights and bullet pointshighlights
Product Q&Aproduct-qa
Product attributesproduct-attributes
Image alt textimage-alt
Google Shopping feed fieldsgoogle-shopping
Agentic Commerce feed fieldsagentic-commerce
Microsoft Shopping feed fieldsmicrosoft-shopping
Shopify feed fieldsshopify
WooCommerce feed fieldswoocommerce

A value that is not in this table is skipped rather than rejected, and is listed in skippedContentTypes (on a synchronous response, or on the job's result) so you can see it was not generated or charged. image-alt needs at least one product image with a public URL.

Leave contentTypes out of a pipeline request and it generates product-description, meta-tags, jsonld-schema, and irl-scenarios.

Synchronous and asynchronous requests

POST /enrichment/pipeline always runs as a durable job: it answers 202 with a job envelope.

POST /enrichment/rules and POST /enrichment/content decide from the size of the request:

  • rules answers inline for up to 5 products.
  • content answers inline for up to 5 products and up to 10 units (products multiplied by content types).
  • A store source always becomes a job.

Anything larger returns 202 with a job envelope. Send "mode": "async" to force a job, or "mode": "sync" to require an inline result. An inline content response is 200, or 207 when some units failed.

POST /enrichment/lookup works the same way. It answers inline for up to 5 products, or 3 when a page is read or the web is searched for each one, and returns a job beyond that.

Poll a job with GET /jobs/{id}, or subscribe to webhooks and skip polling. A job's status is one of pending, running, completed, partial, failed, or cancelled.

Idempotency

Send an Idempotency-Key header (up to 255 characters) on a request that creates a job to make a retry safe. A repeat with the same key returns the original job instead of starting a second one, including while that job is still running: a retry is not refused as a second run. The header has no effect on a request that is answered inline.

Responses

Success responses use { "data": ... }. List endpoints that page by number add meta.pagination with page, pageSize, total, and totalPages. GET /feeds/{id}/enrichments pages by cursor instead and adds meta.cursor with limit, hasMore, and nextCursor. GET /feeds/{id}/export returns the feed file itself, not a JSON envelope.

Responses from the endpoints that check a scope carry an X-Request-Id header. Quote it when you report a problem.

Key management

These endpoints manage API keys for the currently signed-in user. They use session (cookie) auth, not an API key, so call them from a page or script that shares the browser session.

MethodPathPurpose
GET/api/keysList keys for the project you are working in, plus account-wide keys (metadata only).
POST/api/keysCreate a key. Body: name (required), optional env, scopes, rate_limit_per_minute, expires_at, project_id. The plain key is returned only on create.
GET/api/keys/[id]Get one key by ID (metadata only).
PATCH/api/keys/[id]Update a key's name, scopes, rate_limit_per_minute, or expires_at.
DELETE/api/keys/[id]Revoke the key.
POST/api/keys/[id]/rotateIssue a successor key. Body: optional graceHours (default 24). The old key works until the grace period ends.

See API Keys for the fields.

Rate limits

Each key has a requests per minute limit: 120 by default for a live key, and at most 20 for a test key. Responses carry X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset. When the limit is exceeded, the API returns 429 with a Retry-After header. See API Keys for how to set a different limit.

Errors

Errors use the shape { "error": { "code": "...", "message": "...", "details": ... } } with these HTTP statuses:

StatusMeaning
400Invalid request or validation error
401Missing, invalid, or expired API key
402Insufficient credits, test quota exhausted, or subscription required
403Forbidden: a missing scope, or a pinned key naming another project
404No such resource, or it belongs to another account
409An enrichment run is already active for the project
413Request body too large
429Rate limit exceeded
500Server error

Error codes

CodeStatusWhen
VALIDATION_ERROR400The body or query failed validation. details lists the problems.
BAD_REQUEST400The request is well formed but cannot be acted on, for example an unknown export channel.
PROJECT_ID_REQUIRED400The endpoint returns project-scoped rows and the request named no project. Applies to an account-wide key that omitted projectId.
UNAUTHORIZED401No key, an invalid or revoked key, or an expired one. On POST /feeds/{id}/events, the signature did not verify.
INSUFFICIENT_CREDITS402A live key's credit balance is empty.
TEST_QUOTA_EXCEEDED402A test key has used its monthly requests or units.
SUBSCRIPTION_REQUIRED402The project bills through Shopify and cannot run AI work yet. The message says why.
FORBIDDEN403The key lacks the scope the endpoint checks.
PROJECT_SCOPE_MISMATCH403The key is pinned to one project and the request named a different one.
PARTNER_REQUIRED403A /tenants endpoint or the X-Tenant-Id header was used by an account that is not a partner, or a tenant endpoint was called with a key other than the partner's account-wide admin key.
TENANT_SUSPENDED403The tenant the call is for is suspended.
TENANT_NOT_FOUND404X-Tenant-Id or the path names no tenant on this account.
TENANT_LIMIT_REACHED409The partner account holds as many tenants as it is allowed.
NOT_FOUND404No such resource for this account.
RUN_ALREADY_ACTIVE409POST /enrichment/pipeline, or a POST /enrichment/content request that would become a job, was refused because another enrichment run is in progress for the project. Nothing is charged.
PAYLOAD_TOO_LARGE413A POST /ratings/ingest body over 3MB.
RATE_LIMIT_EXCEEDED429The key's requests per minute limit was reached.
NO_IDENTIFIER400A lookup request carried nothing that can be looked up.
INVALID_IDENTIFIER400Every identifier in a lookup request failed validation, for example a barcode with a wrong check digit. details gives the reason for each.
SOURCE_UNAVAILABLE400None of the lookup sources the request named is available to the key. details gives the reason for each.
LOOKUP_CONCURRENCY_LIMIT429Three lookup jobs are already queued or running for the account.
SERVER_ERROR500Something failed on our side. Retry, and quote the X-Request-Id header if it persists.

PROJECT_ID_REQUIRED

{
  "error": {
    "code": "PROJECT_ID_REQUIRED",
    "message": "This endpoint returns project-scoped data. Pass ?projectId=<id>, or use a key pinned to a project."
  }
}

Why you may be seeing this now. GET /feeds and GET /feeds/{id} used to answer an account-wide key with no projectId by merging rows from every project on the account. Nothing in the response said which project each row came from, so there was no safe way to read it. They now ask you to name one. POST /feeds asks the same of an account-wide key, with projectId in the body.

Two ways to fix it, both one-time:

  • add ?projectId=<id> to the request. Ids come from GET /projects.
  • or create a key pinned to a project in Settings, Developer console, Keys, and leave the parameter off.

PROJECT_SCOPE_MISMATCH

{
  "error": {
    "code": "PROJECT_SCOPE_MISMATCH",
    "message": "This API key is scoped to a different project."
  }
}

A pinned key may only act on its own project. Use an account-wide key, or a key pinned to the project you are addressing.

On this page