Integrations
One base URL and one key give your product inference, model discovery, per-request cost, and key management. Paste a prompt below into your coding agent and it does the integration with you — switching over from your current provider, or wiring the gateway in from scratch.
Each prompt is first-person, so pasting it is your instruction and consent. The agent asks before every real choice, never prints your key, and reads the full machine-readable contract from /llms.txt (every route, honored and refused parameters, cost fields, error codes). Both carry this deployment’s URLs (web https://pr-1743.preview.experientiallabs.ai, API https://api-pr-1743.preview.experientiallabs.ai).
/api/v1 routes keep the same path shapes, so the switch is a base-URL change plus a model-id mapping; the first prompt does both.Paste into your coding agent: it finds the existing integration, moves the base URL and key, maps model ids against the live catalog, moves cost reads onto the Cost API, and verifies with one call.
I'm replacing my current model provider or gateway with Experiential Labs asthis project's model gateway. I pasted this myself: treat it as my instructionsand my consent. Work WITH me: at each real choice, ask me ONE clear questionwith numbered options and your recommendation, then wait. Don't guess. Printwhat you do at each step, and never print my full API key (first 8 charactersat most). Read the full machine-readable contract first: https://pr-1743.preview.experientiallabs.ai/llms.txt (baseURLs, every route, honored and refused parameters, cost fields, error codes).Follow it literally.1. Find the current integration. Search this project for the provider's baseURL, its key variable, its SDK/client construction, hardcoded model ids,provider-specific request fields (provider preferences, transforms,fallback model lists, referer/title headers), and any code that reads costor usage from it. Show me the list of files and call sites before changinganything.2. Get my Experiential key. Ask me: "Do you have an xpl_ key already?(1) yes, I'll paste it(2) no, create my account"For (2): ask me for my email (never scavenge one from my files or gitconfig), show me https://pr-1743.preview.experientiallabs.ai/terms and https://pr-1743.preview.experientiallabs.ai/privacy and wait for myagreement, thenPOST https://pr-1743.preview.experientiallabs.ai/api/signup/instant (no auth)Header: Content-Type: application/jsonBody: {"email": "<MY_EMAIL>", "agree": true}On 200 capture api_key. On 409 account_exists tell me to sign in athttps://pr-1743.preview.experientiallabs.ai/signin for a key and stop. On any other error show me the response's`error` text verbatim and stop.Store the key as EXPLABS_API_KEY in my env scheme (.env plus an exampleentry), never in code.3. Switch the base URL. The gateway keeps the path shapes my currentintegration already uses:base URL: https://api-pr-1743.preview.experientiallabs.ai/api/v1auth: Authorization: Bearer $EXPLABS_API_KEY (the ONLY header needed)POST /chat/completions, /responses, /messages (Anthropic Messages API) andGET /models work unchanged. Plain OpenAI or Anthropic SDKs can also use thebare base https://api-pr-1743.preview.experientiallabs.ai/v1. Remove the provider-specific headers and requestfields from step 1: the gateway does provider routing (fallback, caching)itself and unknown parameters may be rejected. Send model + messages andonly the parameters I actually rely on.4. Map model ids. GET https://api-pr-1743.preview.experientiallabs.ai/api/v1/models with my key (free; this does notspend credits) lists the slugs I can call. For each model id from step 1,propose the matching slug (e.g. "claude-fable-5.1") and ask me to confirmthe mapping before replacing. Use slugs EXACTLY as returned.5. Move cost and usage reads over.- Every chat/responses reply carries usage.cost (USD, what I was charged)and usage.is_byok; on a stream it rides the final usage chunk. No flagneeded. Exception: a request sent with Idempotency-Key carries nousage.cost at all (original or replay), so read the field as optional.- One request: read the x-request-id response header and callGET https://api-pr-1743.preview.experientiallabs.ai/api/v1/generation?id=<that id>.- Balance: GET https://api-pr-1743.preview.experientiallabs.ai/api/v1/credits. Recent activity:GET https://api-pr-1743.preview.experientiallabs.ai/api/v1/activity.- Billing feed: GET https://api-pr-1743.preview.experientiallabs.ai/api/v1/usage is the settled per-request export(cost_usd, estimated_cost_usd, real_cost_usd, tokens, attribution_label,api_key_id), newest first inside a lookback window (24h|7d|30d); itsnext_cursor pages OLDER within one call and is not a resume checkpoint.Each run scans from the top and dedupes on the row id.- If I rebill my own customers, pass their stable id as safety_identifier(alias: user) on every request; it comes back as attribution_label.Replace my old provider's cost/usage code with these; show me the difffirst.6. Key management (only if my code creates or rotates keys programmatically).https://api-pr-1743.preview.experientiallabs.ai/api/v1/keys (GET/POST/PATCH/DELETE) requires a PROVISIONING key: anxpl_ key minted with "provisioning": true. The first one is created fromthe dashboard at https://pr-1743.preview.experientiallabs.ai/api-keys (org admin, "Provisioning key" option).Tell me to mint it and paste it as a separate server-side secret; never useit for inference traffic.7. Verify. Make ONE minimal test call (model + messages only, no samplingparameters) with a free promotional model from the /models list, or one Iname. Report the model, that it succeeded, and its usage.cost. If it failswith a credits or activation error, tell me to finish activation at https://pr-1743.preview.experientiallabs.aiand stop; do not retry with another provider. Then run the project'sexisting tests.8. Report back: every file changed, the model-id mapping, what happened to theold provider key (tell me to revoke it at the old provider; don't delete ityourself), and the test call result. Human docs if you need more:https://pr-1743.preview.experientiallabs.ai/docs/integrate.
Paste into your coding agent: it wires a client, attributes every request to your end-customer, builds the billing sync on the settled usage export, and offers key-per-customer.
I'm integrating Experiential Labs into this product as its model gateway: myproduct calls models through it and meters or rebills my own end-users. Ipasted this myself: treat it as my instructions and my consent. Work WITH me:at each real choice, ask me ONE clear question with numbered options and yourrecommendation, then wait. Don't guess. Print what you do at each step, andnever print my full API key (first 8 characters at most). Read the fullmachine-readable contract first: https://pr-1743.preview.experientiallabs.ai/llms.txt (base URLs, every route,honored and refused parameters, cost fields, error codes). Follow it literally.1. Get my Experiential key. Ask me: "Do you have an xpl_ key already?(1) yes, I'll paste it(2) no, create my account"For (2): ask me for my email (never scavenge one from my files or gitconfig), show me https://pr-1743.preview.experientiallabs.ai/terms and https://pr-1743.preview.experientiallabs.ai/privacy and wait for myagreement, thenPOST https://pr-1743.preview.experientiallabs.ai/api/signup/instant (no auth)Header: Content-Type: application/jsonBody: {"email": "<MY_EMAIL>", "agree": true}On 200 capture api_key. On 409 account_exists tell me to sign in athttps://pr-1743.preview.experientiallabs.ai/signin for a key and stop. On any other error show me the response's`error` text verbatim and stop.Store the key as EXPLABS_API_KEY in my env scheme (.env plus an exampleentry), never in code.2. Wire the client. Ask me where (options + your recommendation, based on whatyou see in this project), then wait. Configure an OpenAI-compatible orAnthropic client with:base URL: https://api-pr-1743.preview.experientiallabs.ai/api/v1 (inference, model discovery, cost, andaccount routes under one base; plain OpenAI / Anthropic SDKsmay also use https://api-pr-1743.preview.experientiallabs.ai/v1)auth: Authorization: Bearer $EXPLABS_API_KEY (the ONLY header needed)POST /chat/completions, /responses, or /messages (Anthropic Messages API).Name models by slug EXACTLY as GET https://api-pr-1743.preview.experientiallabs.ai/api/v1/models returns them(free; this does not spend credits). Send model + messages and only theparameters I actually rely on; unknown parameters may be rejected.3. Attribute every request to my end-customer. Pass their stable id assafety_identifier (alias: user) on every request. It comes back asattribution_label on the usage export, so I can group cost and tokens bymy own customer id with ONE key. Ask me what my customer id looks like andwire it through from where my code knows the customer.4. Read cost.- Inline: every chat/responses reply carries usage.cost (USD, what I wascharged) and usage.is_byok; on a stream it rides the final usage chunk.No flag needed, but a request sent with Idempotency-Key carries nousage.cost at all (original or replay), so read it as optional. Show itin my product where it helps; do not treat it as the billing record.- One request: read the x-request-id response header and callGET https://api-pr-1743.preview.experientiallabs.ai/api/v1/generation?id=<that id>.- Balance: GET https://api-pr-1743.preview.experientiallabs.ai/api/v1/credits (data.total_credits - data.total_usage).5. Build the billing sync on the settled export. Ask me which billing system Iuse (Metronome, Orb, Stripe metered billing, my own tables, or none yet),then write a scheduled job that:- reads GET https://api-pr-1743.preview.experientiallabs.ai/api/v1/usage?limit=1000 (settled rows, newest firstinside a lookback window: window=24h|7d|30d, default 7d; filterable byattribution_label, model, api_key_id, status). next_cursor({cursor_ts, cursor_id, cursor_after}, passed back as query params)pages OLDER within this one call and is NOT a checkpoint to resume fromnext run: each run starts at the top, follows next_cursor until a wholepage is older than the last successful run's start time minus a graceperiod covering my longest request, and dedupes on the row id. Scheduleit at least daily; rows older than 30 days are no longer exportable.- lands each row in a local outbox table keyed on the row id (insert, onconflict do nothing) in one local transaction, then in a separatedelivery step pushes unsent rows to the billing system and marks themsent (an external HTTP write cannot share my database transaction; theoutbox makes a crash between the two safe to replay),- sends one usage event per row: customer from attribution_label,transaction_id / idempotency key = the row id, timestamp = created_at,quantity = the cost column I choose (below) plus token counts if I meteron tokens; the margin is a rate in the billing system, not in this job.Cost columns: cost_usd is the platform credits charged; estimated_cost_usdis the attributed value of a BYOK row (served on my own provider key) atcatalog list rates, an estimate and never the provider's invoice;real_cost_usd is the two added together. Ask me whether to billreal_cost_usd (accepting the BYOK estimate) or cost_usd plus tokens onBYOK rows. pricing_known false means unpriced (cost 0), not free.6. Key-per-customer (optional; ask me). If I want each customer isolated totheir own key with independent revocation and a daily USD cap, that needsa PROVISIONING key: an xpl_ key minted with "provisioning": true. Thefirst one comes from the dashboard at https://pr-1743.preview.experientiallabs.ai/api-keys (org admin,"Provisioning key" option); keep it server-side and never use it forinference. With it: POST https://api-pr-1743.preview.experientiallabs.ai/api/v1/keys {name, limit, provisioning}returns the plaintext key exactly once; GET/PATCH/DELETEhttps://api-pr-1743.preview.experientiallabs.ai/api/v1/keys/{hash} list, update (disabled:true revokes), and revoke.A normal inference key gets 403 on every /keys route.7. Verify. Make ONE minimal test call (model + messages only) with a freepromotional model from the /models list, or one I name, carrying a testsafety_identifier. Report the model, that it succeeded, and its usage.cost;then confirm the row shows up on GET https://api-pr-1743.preview.experientiallabs.ai/api/v1/usage with thatattribution_label. If the call fails with a credits or activation error,tell me to finish activation at https://pr-1743.preview.experientiallabs.ai and stop. Then run the project'sexisting tests.8. Report back: every file changed, where the key lives, how customerattribution flows, and the billing job's schedule and cursor storage.Human docs if you need more: https://pr-1743.preview.experientiallabs.ai/docs/integrate, https://pr-1743.preview.experientiallabs.ai/docs/cost-api,and https://pr-1743.preview.experientiallabs.ai/docs/account-api.
Everything is served under one host at https://api-pr-1743.preview.experientiallabs.ai/api/v1. The surface has three families, split across three pages so you can read only what you need:
Wiring a coding agent rather than your own code? See Coding agents for per-tool setup.
One base URL covers serving, cost, and account:
curl https://api-pr-1743.preview.experientiallabs.ai/api/v1/chat/completions \-H "Authorization: Bearer xpl_..." \-H "Content-Type: application/json" \-d '{"model": "claude-fable-5.1","messages": [{"role": "user", "content": "hello"}]}'
Point your client’s base_url at it and change nothing else. The same xpl_ key and base URL work with the OpenAI SDK, the Anthropic SDK, or a raw Authorization: Bearer header. Serving is also available at the bare https://api-pr-1743.preview.experientiallabs.ai/v1 base for OpenAI / Anthropic clients that expect it.
xpl_ key; there is no second account to create. Read-only cost calls use the same key. Only the /api/v1/keys* management family needs a provisioning key — see the Account API.These are transparent relays into the single gateway worker: the request and response bodies are the OpenAI / Anthropic wire formats you already send. All four are rewritten to their /v1 twins before auth, so the /api/v1 base behaves exactly like the bare /v1 base for them.
| Route | Notes |
|---|---|
| POST /api/v1/chat/completions | OpenAI Chat Completions, streaming or not. |
| POST /api/v1/responses | OpenAI Responses API. HTTP or the WebSocket upgrade on the same path. |
| POST /api/v1/messages | Anthropic Messages API (what Claude Code speaks). |
| GET /api/v1/models | Model discovery, relayed 1:1 to the worker's key-scoped /v1/models — the slugs your key can call (public catalog plus your org's own models). Every listed model is callable at https://api-pr-1743.preview.experientiallabs.ai/api/v1. |
| Route | Notes |
|---|---|
| GET /api/v1/models/{author}/{slug}/endpoints | Per-model provider endpoints (the “waterfall”). The {author} segment is accepted for URL compatibility but not used to resolve the model — resolution is by {slug}. |
| GET /api/v1/providers | Provider list. Provider metadata we do not track is omitted rather than faked. |
https://api-pr-1743.preview.experientiallabs.ai/api/v1; you do not configure a second prefix. (Serving is also available at the bare /v1 base.)null or omitted rather than filled with a placeholder. If a value is present, it is real./api/v1/keys* family requires a provisioning key (Account API).GET /api/v1/usage on a schedule and persist the cursor; there is no push webhook yet (Cost API).Next: read what each request costs and how to rebill it on the Cost API, or provision keys programmatically on the Account API.