Docs
Status
OverviewQuickstartSetup promptsThe core loopAuthenticationOverviewModelsThe waterfallAdding modelsData controlsAnthropic APIErrorsIntegrate the gatewayCost APIAccount APICoding agentsCredits & billingSpend & intelligenceTelemetryBecome a providerProvider guideAPI reference

Get started

  • Overview
  • Quickstart
  • Setup prompts
  • The core loop
  • Authentication

Guides

  • Overview
  • Models
  • The waterfall
  • Adding models
  • Data controls
  • Anthropic API
  • Errors

Integrations

  • Integrate the gateway
  • Cost API
  • Account API
  • Coding agents

Billing & usage

  • Credits & billing
  • Spend & intelligence
  • Telemetry

Providers

  • Become a provider
  • Provider guide

Reference

  • API reference
PreviousTelemetryNextProvider guide

Providers

Become a provider

Run an OpenAI-compatible inference endpoint? List it on the marketplace: the gateway routes customer traffic to you, bills at the rates you publish, and shows your lane in the public catalog with measured latency, throughput, and uptime.

Who the marketplace is for

The self-serve lane accepts public OpenAI-compatible https endpoints only. If your service needs a native SDK integration, that is a hand-built engagement: contact us instead of registering. Everything here describes what is built today; anything not yet built is marked planned.

As a provider you control three things:

  • Price. Integer nano-USD rates per million tokens, per model, including optional cached-input, reasoning, and service-tier (flex/priority) rate cards. Decreases apply on approval; increases take effect no sooner than 7 days after you request them.
  • Capacity. You declare limits, and you may reject work at any time by returning HTTP 429: the gateway falls through to another provider instead of penalizing you.
  • Lifecycle. You add models, deprecate them on a schedule, and offboard entirely, without waiting on us to edit anything by hand.

Settled revenue on your lanes accrues to a provider wallet on the platform, net of an agreed platform fee, with payouts on request. The Provider guide covers earnings and day-to-day operations in detail.

Two ways to register

Both doors register the same identity: your slug, endpoint, contact and escalation channels, terms acceptance, and data-policy declaration. Neither ever carries a credential.

  • The manifest PR (canonical): open a pull request against experientiallabs/platform adding one file, providers/<your-slug>/manifest.json. The manifest records your terms acceptance in a reviewed, versioned artifact. Listing models is optional; most providers onboard with identity only and add models in bulk inside the platform after merge. A credential-free CI workflow validates the whole file on every PR, forks included.
  • The in-platform application: an admin of your platform organization opens the org's Inference page and submits a "Become a provider" application with the same declarations. One application may be pending per org at a time; a rejection comes with a readable note and you can re-apply.
A coding agent can prepare the manifest PR for you end to end. Fill in the bracketed facts in the prompt below and paste it into your agent.

Prompt for your integration agent

The prompt carries the full manifest schema, the CI checks the PR must pass, and the hard rules (no secrets in the PR, no invented prices or capabilities, no fabricated data-policy values). Fill in the facts section first; the agent does the rest.

prompt
Prepare a provider onboarding pull request for the Experiential Labs
platform marketplace. Follow these instructions exactly; do not improvise.
## Facts about us (filled in by a human)
- Provider name: [DISPLAY NAME]
- Desired slug: [slug, lowercase, letter first, matching ^[a-z][a-z0-9._-]{0,63}$]
- OpenAI-compatible endpoint base URL: [https://... , public, no query/fragment]
- Auth mode: [house_key if we will issue them an API key after merge, or none]
- Ops contact email: [email]
- Escalation channel: [free text, optional]
- Status page: [public https URL, optional]
- Terms accepted by: [name and role], version [version], at [ISO timestamp with timezone]
- Data policy: retains_prompts=[true/false], retention_days=[int, ONLY if
retains_prompts is true], trains_on_data=[true/false],
zero_data_retention=[true/false], policy_url=[public https URL, optional]
- Declared limits: max_concurrency=[int > 0, optional], advertised_tps=[number > 0, optional]
- Initial models: [list of wire ids with prices, or "none: identity-only PR"]
## The task
Open a PR against https://github.com/experientiallabs/platform (base branch
main) adding exactly one file: providers/<slug>/manifest.json. The directory
name must equal provider.slug inside the file. Touch no other file, with one
exception noted under "CI checks" below.
## The JSON schema (unknown keys are rejected everywhere)
Top level: {"schema_version": 1, "provider": {...}, "limits": {...}?, "models": [...]?}
provider (required object):
- slug: string, ^[a-z][a-z0-9._-]{0,63}$
- display_name: non-empty string
- family: the literal string "openai_compatible" (only value accepted)
- base_url: public https URL, <= 2048 chars, no query string, no fragment,
no localhost/private/internal hosts
- auth_mode: "house_key" or "none"
- contact: {"email": required plain address, "escalation": optional string,
"status_page": optional public https URL}
- terms: {"version": non-empty string, "accepted_by": non-empty string,
"accepted_at": ISO timestamp WITH timezone offset, e.g. 2026-08-25T00:00:00Z}
- data_policy (required): {"retains_prompts": bool, "retention_days": int >= 0
present exactly when retains_prompts is true and omitted when false,
"trains_on_data": bool, "zero_data_retention": bool (may be true only when
retains_prompts and trains_on_data are both false), "policy_url": optional
public https URL}
limits (optional object): {"max_concurrency": int > 0 optional,
"advertised_tps": number > 0 optional}
models (optional array, may be omitted; wire_id unique within the file):
- wire_id: string, ^[A-Za-z0-9][A-Za-z0-9._/:@-]*$
- binding: either {"kind": "existing", "slug": "<catalog model slug>"} or
{"kind": "new", "model": {"slug": ^[a-z][a-z0-9._-]{0,127}$,
"display_name": required, "description": optional,
"context_window": optional int > 0, "max_output_tokens": optional int > 0,
"input_modalities": optional non-empty unique subset of
["text","image","audio","video","pdf"], "huggingface_url": optional,
exactly https://huggingface.co/<org>/<repo>, "release_url": optional https
URL with a dotted host}}
- prices: {"input_nano_usd_per_million": int >= 0 required,
"output_nano_usd_per_million": int >= 0 required,
"cached_input_nano_usd_per_million": optional int >= 0,
"reasoning_nano_usd_per_million": optional int >= 0,
"effective_at": optional ISO timestamp with timezone}. Unit: integer
nano-USD per million tokens (1000000000 = $1.00 per million). Omit a rate to
mean "no such rate"; never use 0 as a placeholder.
- capabilities: object mapping capability name -> bool. Allowed keys ONLY
(the engine's capability vocabulary): supports_developer_messages,
supports_streaming, supports_streaming_tool_arguments,
supports_strict_tools, supports_parallel_tool_calls,
supports_structured_text, supports_stop_sequences, supports_image_input,
supports_image_url_input, supports_video_input, supports_video_url_input,
supports_audio_input, supports_pdf_input, supports_pdf_url_input,
supports_media_handle_input, supports_async_tools,
supports_mid_turn_steering, supports_reasoning_effort_update,
reasoning_effort_required, reports_refusals, reports_cached_input_tokens,
reports_reasoning_tokens. Every model entry MUST declare
"supports_streaming": true.
- context_window: optional int > 0. region: optional string.
- deprecation: optional {"eol_at": timezone-aware timestamp,
"replacement_slug": optional string}. Omit for new lanes.
## CI checks the PR must pass (workflow: "Provider manifests")
1. Schema: the file parses against the schema above; one bad entry rejects
the whole file; the directory name equals provider.slug.
2. Identity guards: the provider slug is not already registered; a wire id
already routed in the catalog may not be proposed as a new model or
re-bound to a different catalog model; a proposed new slug may not
collide with or normalize onto an existing model; binding
"kind": "existing" requires the slug to exist in the catalog. If CI
reports needs-alias-entry, the fix is to add the exact CANONICAL_ALIASES
entry the message spells out (file explabs/gateway/model_aliases.py);
that is the only other file the PR may touch, and only when CI asks.
3. A :free wire id must bind a catalog slug ending in -free.
4. Serving completeness: supports_streaming true on every model; if
reports_cached_input_tokens or reports_reasoning_tokens is true, the
matching rate must be present.
5. Price sanity: all rates are non-negative integers in nano-USD per
million tokens, taken from the provider's real published pricing.
6. Reachability probe: credential-free GET {base_url}/models must complete
a TLS request. Any HTTP status (401, 404, 5xx) counts as reachable; DNS
failure, connection failure, or resolution to a private IP fails.
## Do NOT
- Do not put any API key, token, or secret anywhere in the PR. Credentials
are exchanged out-of-band after merge; a PR containing a secret is closed
and the secret must be rotated.
- Do not bind a wire id to a different model's identity, and do not propose
a new model for something the catalog already carries under another name.
If unsure whether a model exists in the catalog, bind nothing and say so
in the PR description; identity-only PRs are normal.
- Do not invent prices, use negative numbers, use floats for money, or use
0 to mean "unknown". Omit optional rates you do not have.
- Do not invent capability keys or set capabilities you have not verified
against the real endpoint.
- Do not fabricate the data_policy values; they are contractually binding.
If a value is not confirmed by a human, stop and ask.
- Do not touch any file other than providers/<slug>/manifest.json (and a
CANONICAL_ALIASES entry only when CI explicitly asks for it).
## PR description
State who the provider is, link the pricing page and the data policy page,
and note whether models are included or the PR is identity-only.
## What happens after merge
A platform admin links the provider's platform organization (it gains a
Inference page in the sidebar), the API key is exchanged out-of-band and
stored in Vault (house_key mode), and model additions, price changes,
limits, and smoke checks are then managed inside the platform as
admin-approved requests, not through further PRs. New lanes start as
canaries at the tail of the fallback chain. Price increases require an
effective date at least 7 days out; decreases apply on approval.

The data-policy declaration

Registration requires a machine-readable declaration of what you do with customer prompt and completion data: whether content persists after the response (and for how long), whether you train on it, and an explicit zero-data-retention claim that may only be true when both are false. The declaration is self-reported: the platform surfaces it to customers, who filter and choose providers by it, and binds you to it contractually through the terms acceptance recorded alongside. A false declaration is a terms violation and grounds for immediate offboarding. If your practice changes, update the declaration before the change takes effect.

What happens after

  1. Review. A human reviews every provider registration. Merging the PR, or a platform admin approving your application, creates your registry row and links your organization; the Inference page becomes your operating console.
  2. Key exchange. For house_key endpoints you issue us an API key through a private channel after registration. It is stored in our secrets vault, never appears in a PR or the manifest, and is never displayed back once stored (rotation replaces it).
  3. Canary, then live. Your record starts in onboarding. Once the credential is stored and your first lane passes a smoke check, an admin moves it to canary and later to live. Every new lane starts at the tail of its model's fallback chain, serving real traffic only when the lanes above it fail or shed, and is promoted by an admin informed by observed stats.

From there, day-to-day changes never go through PRs: you submit model, price, and limit requests from the Inference page and a platform admin approves them. The Provider guide is the operational reference once you are onboarded.