License a real person before you generate them.

Preview · not live v0 is in private testing. This page describes the API as it will ship; the endpoints don't respond on somata.me yet.

Somata is the licensing platform for real people in AI content. If your app or agent creates images or video of an identifiable real person, ask Somata first. You get a decision, and once the clearance is paid, a signed Clearance SID to attach to every output.

Base URLhttps://somata.me/api (paths below start /v1) Preview · not live
AuthAuthorization: Bearer smk_<test|live>_…
SpecOpenAPI 3.1, published when v0 goes live
Agent index/llms.txt
FormatJSON in and out, snake_case. Errors are {"error": {"code", "message", ...}}.
MCPhttps://somata.me/mcp Proposed · not live
Versionv0 preview. Details may change before it goes live.

Rules for autonomous agents

If you are an AI agent acting for a person or business, these rules apply to every request. They will be part of the API terms, and keys that break them will be revoked.

Before generating any image or video of a real person:
  1. MUSTCall POST /v1/quotes for that person, with the real campaign, media, territory and term.
  2. MUST NOTGenerate when the decision is deny, or before the quote's SID is active. A quote can stay refer after a person approves it: the SID status is the go signal.
  3. MUSTGenerate only after the quote has an active SID, and only within its scope and dates.
  4. MUST NOTPay on anyone's behalf. Hand the checkout_url to a human.
  5. MUSTAttach the SID and verify_url to every output's metadata and delivery notes.
  6. MUST NOTStore or reuse reference assets after their URL expires, or outside the SID's term.
  7. MUSTCall GET /v1/clearances/{sid}/verify before reusing an output, and stop if is_valid_now is false.
  8. MUSTPoll no more than once a minute. There are no webhooks in v0.
Paste into your agent's system prompt
You may only create images or video of a real, identifiable person through Somata.
Before generating, call request_quote (POST /v1/quotes) with the real campaign details.
- decision "deny": do not generate. Tell the person you're working for why, using `reasons`.
- otherwise: do not generate yet. Poll get_quote at most once a minute until the SID status is "active" (decision can stay "refer" after a person approves it). Stop, and do not generate, if the decision becomes "deny" or the SID is "expired" or "voided".
- when get_quote shows a checkout_url: give it to the person you're working for. Never pay yourself.
- when the SID status is "active": generate only within its scope and dates.
Attach the SID and verify_url to every output. Verify before reusing an output.

Keys and auth

KeyCan doWrites anything?
smk_test_…GET /v1/talent and dry-run POST /v1/quotesNo. quote_id is always null.
smk_live_…Every endpointYes. Quotes are real Clearance Requests.

Keys are issued by Somata to an approved organisation and are bound to it. You can only see your own organisation's quotes and SIDs; anything else returns 404. During the private test, keys go to organisations Somata works with directly: register your organisation to ask for one. Send keys only in the Authorization header, never in URLs.

The flow

  1. GET /v1/talent?category=fashion

    Find a person. Only Talent who opted in to AI apps are returned; everyone else does not exist to the API. Use their id (tal_…).

  2. POST /v1/quotes

    Describe the use. You get a decision straight away. A test key stops here.

  3. GET /v1/quotes/{quote_id}

    Poll until a SID appears. In v0 Somata reviews every quote before issuing a SID, so expect minutes to hours, not milliseconds. When the SID is pending_payment, checkout_url is set.

  4. checkout_url → a human pays

    Payment completes on a Somata page. The SID becomes active and the Talent is paid.

  5. GET /v1/clearances/{sid}/assets

    Download the Talent's reference images through short-lived signed URLs. Every download is recorded.

  6. Generate · attach sid + verify_url

    Make the content within the SID's scope. Put the SID in the file metadata and the delivery notes.

  7. GET /v1/clearances/{sid}/verify

    Check the signature and dates whenever the content is published or reused.

Decisions

decisionMeaningWhat to do
clearInside the Talent's terms.Poll for the SID, then hand checkout_url to a human. Don't generate before the SID is active.
referSomata or the Talent needs to review it.Poll GET /v1/quotes/{id}. Don't generate until the SID is active.
denyNot available for this use. reasons says why, e.g. talent_unavailable, category_not_permitted.Don't generate. Don't retry the same request.
pendingEvaluation hasn't finished.Poll. It resolves to one of the above.
Quotes go to refer when any of these reasons appear: tools_provider_unclassified:<provider> (Somata hasn't confirmed that provider's terms yet), tools_trains_on_inputs:unknown|yes, tools_retains_inputs:unknown|yes. Name the providers you actually use, and set the two tools_* fields truthfully.

Endpoints

GET /v1/talent · any key

Query: category (one of the category tokens), search (display name), limit (1–100, default 50). Thumbnails are watermarked previews with a 15-minute URL.

{ "data": [ { "id": "tal_cr7reyes0k4m2q", "display_name": "Camila Reyes",
    "country_of_residence": "GB", "permitted_categories": ["fashion", "beauty", "lifestyle"],
    "thumbnail": { "url": "https://somata.me/…", "expires_at": "2026-10-09T10:15:00Z" } } ] }

POST /v1/quotes · any key

FieldTypeNotes
talent_idstringRequired. tal_…
campaign_namestring ≤ 200Required.
campaign_descriptionstring ≤ 5000Required. What will be made, in plain words.
end_brandstring ≤ 500The brand the content is for.
categoryenumRequired. fashion, beauty, lifestyle, soft_drinks, automotive, sport, travel, tech_consumer, other
territory_countriesstring[]Required. ISO 3166 alpha-2, e.g. ["GB","FR"]
media_channelsenum[]Required. instagram, tiktok, youtube, facebook, x, ooh, tv_ctv, digital_display, press, in_store, brand_website
duration_monthsinteger 0–120Required.
final_outputsinteger 0–100000Required. How many finished pieces.
synthetic_typeenumRequired. still, video, both
tool_providersenum[]Required. e.g. higgsfield, runway, veo, kling, other
feeobjectRequired. {"amount": "250.00", "currency": "GBP"}. Send amount as a string.
tools_trains_on_inputs, tools_retains_inputsenumyes, no, unknown. Default unknown, which sends the quote to review. Say what your provider actually does.
voice_requested, ai_trainingbooleanDefault false. Most Talent say no to both.
Requestsmk_live_…
curl https://somata.me/api/v1/quotes \
  -H "Authorization: Bearer $SOMATA_KEY" -H "Content-Type: application/json" \
  -d '{ "talent_id": "tal_cr7reyes0k4m2q", "campaign_name": "SS26 rooftop",
        "campaign_description": "Six AI stills of Camila in the camel trench, Paris rooftop at dusk.",
        "end_brand": "Maison Lacourt", "category": "fashion",
        "territory_countries": ["GB","FR","DE"], "media_channels": ["instagram"],
        "duration_months": 3, "final_outputs": 6, "synthetic_type": "still",
        "tool_providers": ["higgsfield"], "fee": { "amount": "250.00", "currency": "GBP" } }'
201 Createdlive key
{ "quote_id": "cr_9f2k4qhm3x0ab1zz", "dry_run": false, "talent_id": "tal_cr7reyes0k4m2q",
  "decision": "refer", "reasons": ["tools_trains_on_inputs:unknown", "tools_retains_inputs:unknown",
              "tools_provider_unclassified:higgsfield"],
  "missing_fields": [], "fee": { "amount": "250.00", "currency": "GBP" } }

GET /v1/quotes/{quote_id} · live key

The quote above, plus status, sid ({"id", "status"} or null), checkout_url and checkout_error. A 502 checkout_unavailable with retryable: true means try again shortly.

{ "quote_id": "cr_9f2k4qhm3x0ab1zz", "dry_run": false, "status": "evaluated", "decision": "refer",
  "sid": { "id": "sid_7q4k2c9fhm3x0ab1", "status": "pending_payment" },
  "checkout_url": "https://checkout.stripe.com/c/pay/…", "checkout_error": null, … }

GET /v1/clearances/{sid}/assets · live key

Signed URLs for the Talent's reference images, for an active, paid SID inside its dates. 403 access_denied carries a reason such as payment_not_satisfied or sid_outside_effective_window.

{ "sid": "sid_7q4k2c9fhm3x0ab1", "assets": [
  { "id": "rm_0a1b2c3d4e5f6g7h", "subtype": "front_headshot", "url": "https://somata.me/…", "expires_at": "…" } ] }

GET /v1/clearances/{sid}/verify · live key

{ "sid": "sid_7q4k2c9fhm3x0ab1", "status": "active", "signature_valid": true, "is_valid_now": true,
  "issued_at": "2026-10-08T14:02:00Z", "expires_at": "2027-01-06T23:59:59Z",
  "scope_summary": { … }, "restrictions": ["no_voice", "no_ai_training",
  "no_reusable_model_beyond_campaign", "no_temporary_production_model"] }

Anyone can also check a SID without a key at https://somata.me/verify/{sid}.

Errors

Status · codeMeaningRetry?
400 invalid_requestBad input. field names the problem.No. Fix the request.
401 unauthorizedMissing, malformed, unknown or revoked key.No.
403 organisation_not_approvedYour organisation isn't approved.No.
403 access_deniedAssets only: the SID isn't usable yet or any more. See reason.After the cause changes.
404 not_foundDoesn't exist, or isn't your organisation's.No.
409 live_key_requiredTest keys can't call this endpoint.With a live key.
502 checkout_unavailableCouldn't create the payment session.Yes, after a pause.

MCP server Proposed · not live

A Model Context Protocol server wrapping the same endpoints one to one, so agents in Claude, Cursor and similar clients can license a person as a tool call. Same keys, same rules. Don't configure it yet: this section shows the planned shape.

Client config (planned)mcp.json
{ "mcpServers": { "somata": {
    "url": "https://somata.me/mcp",
    "headers": { "Authorization": "Bearer ${SOMATA_KEY}" } } } }

${SOMATA_KEY} stands for your key, read from an environment variable. How a client writes that reference differs (for example ${env:SOMATA_KEY} in Cursor); never paste the key itself into a file you commit.

ToolWrapsInput
list_talentGET /v1/talentcategory?, search?, limit?
request_quotePOST /v1/quotesThe quote fields above
get_quoteGET /v1/quotes/{id}quote_id
get_clearance_assetsGET /v1/clearances/{sid}/assetssid
verify_clearanceGET /v1/clearances/{sid}/verifysid

There is deliberately no tool that pays. Payment stays with a human.

Limits in v0

NotificationsNo webhooks. Poll GET /v1/quotes/{id} at most once a minute, and stop if the decision becomes deny or the SID is expired or voided.
Rate limitsNo published limits or headers yet. Keys that hammer the API are revoked.
PaginationNone. GET /v1/talent returns up to limit results.
IssuingEvery SID is issued after Somata review. Instant issuing comes later.
Talent shownOnly Talent who opted in to AI apps and manage their own profile.

llms.txt

The same rules in plain text, served at /llms.txt for agents that read that first.

# Somata
> The licensing platform for real people in AI content. Ask Somata before generating an identifiable real person.

Status: v0 preview, in private testing. The endpoints below are not live yet.

## Rules
- Call POST /api/v1/quotes before generating any real person. Generate only once the quote's SID is active, within its scope and dates.
- deny: do not generate. Otherwise poll GET /api/v1/quotes/{id} at most once a minute; generate only once its SID status is active (decision can stay refer after a person approves it). Stop if the decision becomes deny or the SID is expired or voided.
- Never pay on anyone's behalf: give checkout_url to a human.
- Attach the SID and verify_url to every output. Verify before reuse.

## Docs
- [Developer guide](https://www.somata.me/developers)
- Verify a SID: https://somata.me/verify/<sid> (replace <sid> with the Clearance SID)