> ## Documentation Index
> Fetch the complete documentation index at: https://developers.meshapi.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# MCP Capability Reference

> What the MCP server does not do, why, and what to do instead.

The MCP server does not expose every action the API offers. This page lists what is missing, so you can tell a deliberate omission from a gap, and says what to do instead. An agent connected over MCP can read the same entries from the server itself.

## Not offered over MCP, by design

These actions are deliberately not tools, so an agent holding one key can never mint, widen or hand out access. Each entry says who can do it and how.

### Add someone to a team

**Who can do this:** A caller holding members:write on that team.

`POST /v1/orgs/current/teams/{team_id}/members`

* Auth: User session JWT only; responds 201
* Permission: `members:write, team-scoped`
* Body `user_id`: an existing member of the organization
* Body `role`: admin, member or viewer; defaults to member

Worth knowing:

* The user must already be an organization member, or the call is refused.
* An org owner or admin already has implicit team admin access, so adding one is a 409.
* Adding someone who is already an explicit team member is a 409.

### Create an admin key

**Who can do this:** An organization member holding the keys:write permission, signed in with a user session (a mak\_ admin key cannot mint another).

`POST /v1/admin-keys`

* Auth: User session JWT only; responds 201
* Permission: `keys:write`
* Body `name`: string
* Body `permissions`: list, at least one; only these seven are grantable - keys:read, keys:write, org:read, alerts:read, alerts:write, limits:read, limits:write - and only ones the caller already holds, at a scope the caller already holds
* Body `scope`: self, team or org
* Body `team_id`: required when scope is team, forbidden otherwise
* Body `expires_at`: required, no default; must include a UTC offset and be at most 90 days from now

Worth knowing:

* The plaintext mak\_ key is returned once, in the creation response.
* A banned user is refused even with a valid session.
* Rotation is not revocation: during the grace window both the old and the new key work.

### Create an alert channel

**Who can do this:** An organization member holding alerts:write.

`POST /alerts/channels`

* Auth: User session JWT or a mak\_ admin key; responds 201
* Permission: `alerts:write`
* Body `channel_type`: required; email, slack or webhook
* Body `destination`: required; the address or URL to deliver to
* Body `is_enabled`: default true

Worth knowing:

* A webhook channel is minted a signing secret and the plaintext comes back once as signing\_secret; no later read returns it, because only the Secret Manager reference is kept.
* A webhook destination is resolved and checked at registration, so a host pointing at a private or reserved address is a 422.
* Outbound webhooks must be enabled for the deployment, or a webhook channel is refused.

### Create an inference API key

**Who can do this:** An organization member holding keys:write.

`POST /v1/keys`

* Auth: User session JWT or a mak\_ admin key; responds 201
* Permission: `keys:write`
* Body `label`: optional name
* Body `org_id`: optional; the org to create the key in
* Body `team_id`: optional

Worth knowing:

* The plaintext rsk\_ key is returned once.
* A banned account is refused.

### Create a custom organization role

**Who can do this:** An organization owner or admin who may manage roles.

`POST /v1/orgs/current/roles`

* Auth: User session JWT only; responds 201
* Permission: `org:read, plus the right to manage roles`
* Body `name`: required
* Body `slug`: optional; derived from name when omitted
* Body `scope`: self, team or org
* Body `permissions`: required list of organization permissions

Worth knowing:

* A role may not grant a permission, or a scope, the caller does not already hold.
* An empty permissions list is refused rather than stored: it would read as authority and confer none.
* A slug already used in the organization is refused.

### Invite someone to the organization

**Who can do this:** An organization member holding members:write at organization scope.

`POST /v1/orgs/current/members`

* Auth: User session JWT only; responds 201
* Permission: `members:write`
* Body `email`: required
* Body `role`: admin, member or viewer; defaults to member - owner cannot be invited or assigned, use POST /v1/orgs/current/transfer-ownership
* Body `team_id`: optional team to place them in
* Body `custom_role_ids`: optional list of custom role ids, at most 100

Worth knowing:

* This creates a pending invitation and mails a magic link; the invitee joins through POST /v1/invitations/accept.
* An email that already belongs to a member is a 409.
* custom\_role\_ids adds permissions on top of role; it never replaces it.

### Register AWS Bedrock credentials

**Who can do this:** A signed-in member of the organization, acting on their own account's credentials.

`POST /v1/provider-keys/aws`

* Auth: User session JWT only; responds 201
* Body `credential_type`: required; bedrock\_api\_key or iam\_credentials, and it picks the fields below
* Body `api_key`: bedrock\_api\_key mode only
* Body `access_key_id`: iam\_credentials mode only
* Body `secret_access_key`: iam\_credentials mode only
* Body `region`: required AWS region
* Body `team_id`: required
* Body `label`: optional
* Body `allow_fallback`: default true
* Body `allowed_models`: optional list of model ids or brand/\* entries

Worth knowing:

* The credentials are validated against AWS before anything is stored; an invalid pair is a 422 and leaves no row and no secret.
* A Bedrock API key is permanently tied to the region it was created in.
* allow\_fallback: false stops a failing key falling back to Mesh's own credentials.
* Validation probes are rate-limited per account.
* The row is created inactive; activate it with PATCH /v1/provider-keys/\{pk\_id} and `{"is_active": true}`, or routing will not use it.

### Register Azure AI Foundry credentials

**Who can do this:** A signed-in member of the organization, acting on their own account's credentials.

`POST /v1/provider-keys/azure-foundry`

* Auth: User session JWT only; responds 201
* Body `api_key`: required; the project's primary or secondary key
* Body `endpoint`: required; the full project endpoint URL, normalised on the way in
* Body `team_id`: required
* Body `label`: optional
* Body `allow_fallback`: default true
* Body `allowed_models`: optional list of model ids or brand/\* entries

Worth knowing:

* Both values are validated against Azure before anything is stored.
* azure\_foundry is the live provider; the older azure slug is retired and cannot be registered.
* The row is created inactive; activate it with PATCH /v1/provider-keys/\{pk\_id} and `{"is_active": true}`, or routing will not use it.

### Register a single-string provider key

**Who can do this:** An organization member holding provider\_keys:write.

`POST /v1/provider-keys/{provider}`

* Auth: User session JWT only; responds 201
* Permission: `provider_keys:write`
* Body `api_key`: required
* Body `team_id`: required
* Body `label`: optional
* Body `allow_fallback`: default true
* Body `allowed_models`: optional list of model ids or brand/\* entries

Worth knowing:

* The provider must support key-based BYOK; GET /v1/provider-keys/supported lists them and anything else is a 404.
* Order is catalogue check, probe, store, insert, so a key that cannot be routed or does not work leaves behind neither a secret nor a row.
* The row is created inactive; activate it with PATCH /v1/provider-keys/\{pk\_id} and `{"is_active": true}`, or routing will not use it.

### Register an OpenAI key

**Who can do this:** A signed-in member of the organization, acting on their own account's credentials.

`POST /v1/provider-keys/openai`

* Auth: User session JWT only; responds 201
* Body `api_key`: required
* Body `team_id`: required
* Body `label`: optional
* Body `allow_fallback`: default true
* Body `allowed_models`: optional list of model ids or brand/\* entries

Worth knowing:

* The key is validated against OpenAI before it is stored; an invalid one is a 422.
* Validation probes are rate-limited per account.
* The row is created inactive; activate it with PATCH /v1/provider-keys/\{pk\_id} and `{"is_active": true}`, or routing will not use it.

### Register a provider key by Secret Manager reference

**Who can do this:** A signed-in user, for their own account: owner may only name the caller.

`POST /v1/provider-keys/`

* Auth: User session JWT only; responds 201
* Body `provider`: provider slug, default openrouter
* Body `secret_ref`: required; a Secret Manager version resource name whose secret id starts with routerv-byok-\<owner>-
* Body `label`: optional
* Body `org_id`: optional
* Body `team_id`: optional
* Body `allowed_models`: optional list of model ids or brand/\* entries

Worth knowing:

* An UPSERT: posting again for a provider you already hold repoints that key instead of creating a second one, and is audited as provider\_key.updated.
* A raw credential is refused with a 422 whenever a GCP project is configured; use the per-provider routes below to register one by value.

### Register a Vertex AI service account

**Who can do this:** A signed-in member of the organization, acting on their own account's credentials.

`POST /v1/provider-keys/vertex`

* Auth: User session JWT only; responds 201
* Body `project_id`: required
* Body `private_key_id`: required
* Body `private_key`: required
* Body `client_email`: required
* Body `client_id`: required
* Body `client_x509_cert_url`: required
* Body `token_uri`: defaults to [https://oauth2.googleapis.com/token](https://oauth2.googleapis.com/token) and is validated
* Body `region`: optional; omit or send global for the adapter default
* Body `team_id`: optional
* Body `org_id`: optional
* Body `label`: optional
* Body `allow_fallback`: default true
* Body `allowed_models`: optional list of model ids or brand/\* entries

Worth knowing:

* The service account needs roles/aiplatform.user and aiplatform.endpoints.predict.
* It is validated against Vertex AI before anything is stored; an invalid account is a 422.
* token\_uri is checked against an allowed host, so an arbitrary one is refused.
* The row is created inactive; activate it with PATCH /v1/provider-keys/\{pk\_id} and `{"is_active": true}`, or routing will not use it.

### Register an SSO identity provider

**Who can do this:** A signed-in organization owner or admin holding org:write at organization scope.

`POST /v1/orgs/current/sso`

* Auth: User session JWT only; responds 201
* Permission: `org:write, and the org role owner or admin`
* Body `issuer`: required; the IdP's OIDC issuer URL
* Body `client_id`: required
* Body `client_secret`: required; stored in Secret Manager and never returned
* Body `domain`: required; the email domain this provider signs in

Worth knowing:

* This registers a new way to sign in to the organization, so it is a credential, not a setting.
* org:write alone is not enough: an organization API key holds it with no role, and the route needs the owner or admin role.
* It needs the Enterprise SSO entitlement, and serves no sign-in until the domain is verified.

### Rotate an admin key

**Who can do this:** An organization member holding keys:write, who could create the same key today.

`POST /v1/admin-keys/{key_id}/rotate`

* Auth: User session JWT only; responds 201
* Permission: `keys:write`
* Body `grace_hours`: optional; defaults to 24, clamped to 168
* Body `expires_at`: optional; UTC offset, at most 90 days out; omit to inherit the old key's lifetime

Worth knowing:

* The successor's plaintext is returned once.
* Rotation is not revocation: the old key keeps working until the grace window ends.

### Rotate an alert channel's signing secret

**Who can do this:** An organization member holding alerts:write.

`POST /alerts/channels/{channel_id}/rotate-secret`

* Auth: User session JWT or a mak\_ admin key
* Permission: `alerts:write`

Worth knowing:

* The new signing secret is returned once; only its Secret Manager reference is stored.
* Rotation is not revocation: the previous secret keeps verifying for WEBHOOK\_SECRET\_GRACE\_HOURS so the receiver can cut over.
* Only a webhook channel has a signing secret; any other type is a 422.

### Replace a member's custom roles

**Who can do this:** An organization owner or admin who may manage roles.

`PUT /v1/orgs/current/members/{target_user_id}/roles`

* Auth: User session JWT only
* Permission: `members:read, plus the right to manage roles`
* Body `role_ids`: the complete set the member should hold, at most 100

Worth knowing:

* SET semantics: an empty list clears every assignment.
* A role the caller could not grant themselves is refused.
* Assignments key on the membership row, so a member who was removed and re-invited starts from none.

### Set up auto-recharge

**Who can do this:** Any signed-in user, for their own account.

`POST /v1/auto-recharge/setup`

* Auth: User session JWT only; responds 201
* Body `recharge_amount_usd`: default 10.00; bounded by the configured minimum and maximum
* Body `threshold_usd`: default 10.00; must not exceed the configured maximum
* Body `return_url`: required

Worth knowing:

* This creates a Cashfree ON\_DEMAND mandate for a human to authorise; the mandate is not active until the AUTH webhook arrives.
* A suspended account is refused with 403 payments\_unavailable.
* With TURNSTILE\_ENFORCED on it needs an x-captcha-response token, and with BILLING\_PROFILE\_REQUIRED\_FOR\_PAYMENT on it answers 409 billing\_profile\_required.
* Charges on a mandate already authorised are not gated by this route.

### Start a Cashfree checkout for credits

**Who can do this:** Any signed-in user, paying for their own account.

`POST /v1/checkout/cashfree/create-custom-payment`

* Auth: User session JWT only
* Body `amount`: required; INR before GST, must be positive
* Body `country`: optional; an attested country from the load balancer wins
* Body `gstin`: optional
* Body `couponCode`: optional
* Body `gatewayFeePct`: optional; the rate the page displayed, refused if it has changed

Worth knowing:

* Returns a payment-session id for cashfree-js to open; nothing is charged by this call.
* The FX rate is pinned on the pending row, so the credit is the amount the customer was quoted; no rate at all is a 503.
* A suspended account is refused with 403 payments\_unavailable.
* With TURNSTILE\_ENFORCED on it needs an x-captcha-response token, and with BILLING\_PROFILE\_REQUIRED\_FOR\_PAYMENT on it answers 409 billing\_profile\_required until the org has a billing profile.

### Start a Stripe checkout for credits

**Who can do this:** Any signed-in user, paying for their own account.

`POST /v1/checkout/stripe/create-custom-payment`

* Auth: User session JWT only
* Body `amount`: required; USD cents, must be positive
* Body `currency`: must be usd
* Body `country`: optional; an attested country from the load balancer wins
* Body `gstin`: optional
* Body `couponCode`: optional
* Body `description`: optional
* Body `gatewayFeePct`: optional; the rate the page displayed, refused if it has changed

Worth knowing:

* Returns a hosted-checkout URL for a human to complete; nothing is charged by this call.
* A fully-covering coupon credits the balance directly and returns free: true with no gateway redirect.
* A suspended account is refused with 403 payments\_unavailable.
* With TURNSTILE\_ENFORCED on it needs an x-captcha-response token, and with BILLING\_PROFILE\_REQUIRED\_FOR\_PAYMENT on it answers 409 billing\_profile\_required until the org has a billing profile.

### Test AWS Bedrock credentials without saving them

**Who can do this:** A signed-in member of the organization, acting on their own account's credentials.

`POST /v1/provider-keys/test/aws`

* Auth: User session JWT only; responds 200 with `{"status": "ok"}`
* Body `credential_type`: bedrock\_api\_key or iam\_credentials
* Body `api_key`: bedrock\_api\_key mode only
* Body `access_key_id`: iam\_credentials mode only
* Body `secret_access_key`: iam\_credentials mode only
* Body `region`: required AWS region
* Body `team_id`: required by the shared schema, unused here

Worth knowing:

* The credential travels in the request body and is not stored; invalid credentials are a 422.
* Probes are rate-limited per account, shared with registration.
* To check a key you already registered, POST /v1/provider-keys/test/\{pk\_id}/aws instead, which sends no credential.

### Test Azure AI Foundry credentials without saving them

**Who can do this:** A signed-in member of the organization, acting on their own account's credentials.

`POST /v1/provider-keys/test/azure-foundry`

* Auth: User session JWT only; responds 200 with `{"status": "ok"}`
* Body `api_key`: required
* Body `endpoint`: required; the full project endpoint URL

Worth knowing:

* Both values travel in the request body and are not stored; there is no team\_id on this shape.
* To check a pair you already registered, POST /v1/provider-keys/test/\{pk\_id}/azure-foundry instead.

### Test an OpenAI key without saving it

**Who can do this:** A signed-in member of the organization, acting on their own account's credentials.

`POST /v1/provider-keys/test/openai`

* Auth: User session JWT only; responds 200 with `{"status": "ok"}`
* Body `api_key`: required
* Body `team_id`: required by the shared schema, unused here

Worth knowing:

* The key travels in the request body and is not stored.
* To check one you already registered, POST /v1/provider-keys/test/\{pk\_id}/openai instead.

### Test a Vertex AI service account without saving it

**Who can do this:** A signed-in member of the organization, acting on their own account's credentials.

`POST /v1/provider-keys/test/vertex`

* Auth: User session JWT only; responds 200 with `{"status": "ok"}`
* Body `project_id`: required
* Body `private_key`: required, with the other service-account fields
* Body `client_email`: required
* Body `region`: optional

Worth knowing:

* The service account travels in the request body and is not stored.
* An account that is valid but lacks the Vertex AI permissions is a 422 too.
* To check one you already registered, POST /v1/provider-keys/test/\{pk\_id}/vertex instead.

### Transfer organization ownership

**Who can do this:** The current organization owner, and nobody else.

`POST /v1/orgs/current/transfer-ownership`

* Auth: User session JWT only
* Body `user_id`: the auth user id of an existing member

Worth knowing:

* The caller is demoted to admin and the target promoted to owner, atomically.
* The target must already be a member, or the call is a 404.
* A member whose account is banned cannot be made owner.

### Repoint or disable an alert channel

**Who can do this:** An organization member holding alerts:write.

`PATCH /alerts/channels/{channel_id}`

* Auth: User session JWT or a mak\_ admin key
* Permission: `alerts:write`
* Body `destination`: the new address or URL
* Body `is_enabled`: optional

Worth knowing:

* Repointing a webhook channel sends the organization's signed deliveries to the new URL under the signing secret already in force, which this route neither rotates nor returns.
* Changing an email destination clears verified\_at and kills any live verification token: consent is to an address, not to the row.
* channel\_type cannot be changed here, and the new destination is validated like the original.

### Change an inference API key's reach

**Who can do this:** An organization member holding keys:write; an admin or owner for any key in the org, a member only for their own.

`PATCH /v1/keys/{key_id}`

* Auth: User session JWT or a mak\_ admin key
* Permission: `keys:write`
* Body `allowed_models`: replaces the allowlist, which is what the key may reach
* Body `blocked_models`: applied after allowed\_models, deny wins
* Body `spend_cap_usd`: raises or lowers the cap
* Body `rpm`: requests per minute
* Body `rpd`: requests per day
* Body `tpm`: tokens per minute
* Body `model_limits`: per-model overrides
* Body `max_concurrent_sessions`: at least 1, or null to fall back to the system default
* Body `status`: active or suspended
* Body `routing_policy`: inline retry and fallback policy, or null to clear it
* Body `routing_policy_template_id`: attach a template; sending both it and an inline policy is a 422
* Body `api_version`: dated version pin, or null to inherit the baseline
* Body `pii_policy`: inline PII redaction policy, or null to fall through to the org default
* Body `body_log_policy`: inline body-log policy, or null to fall through to the org default
* Body `fixed_provider`: hard provider pin, or null to clear it
* Body `allowed_ips`: IP allowlist; null or an empty list lifts it
* Body `strict_params`: the key's strict-params default
* Body `label`: optional
* Body `default_model`: optional

Worth knowing:

* This widens as well as narrows: allowed\_models, spend\_cap\_usd and the rate limits all change what an existing credential may do.
* Setting an inline routing\_policy detaches any template, and attaching a template clears any inline policy.
* allowed\_ips of null or \[] lifts the allowlist rather than refusing every address.

### Change the auto-recharge amount or threshold

**Who can do this:** Any signed-in user, for their own account.

`PATCH /v1/auto-recharge`

* Auth: User session JWT only
* Body `recharge_amount_usd`: bounded by the configured minimum and maximum
* Body `threshold_usd`: must not exceed the configured maximum
* Body `is_active`: turns the mandate's charging on or off

Worth knowing:

* It changes how much money moves automatically: the amount can be raised to the configured maximum, and is\_active turns charging back on, without a further authorisation step.
* It needs a mandate that is not cancelled; otherwise it is a 404 pointing at POST /v1/auto-recharge/setup.
* DELETE /v1/auto-recharge cancels the mandate outright.

### Rotate AWS Bedrock credentials

**Who can do this:** A signed-in member of the organization, acting on their own account's credentials.

`PATCH /v1/provider-keys/aws/{pk_id}`

* Auth: User session JWT only
* Body `api_key`: rotates a bedrock\_api\_key credential
* Body `access_key_id`: with secret\_access\_key, rotates an iam\_credentials one
* Body `secret_access_key`: sent together with access\_key\_id
* Body `region`: optional; validated before it is stored
* Body `label`: optional
* Body `allow_fallback`: optional
* Body `allowed_models`: optional list of model ids or brand/\* entries

Worth knowing:

* Omit the credential fields to change metadata only; the stored secret is left alone.
* A rotation is validated against AWS before it replaces the stored credential.
* The key must already be a Bedrock key, or the call is a 422.

### Rotate Azure AI Foundry credentials

**Who can do this:** An organization member holding provider\_keys:write.

`PATCH /v1/provider-keys/azure-foundry/{pk_id}`

* Auth: User session JWT only
* Permission: `provider_keys:write`
* Body `api_key`: rotates the credential
* Body `endpoint`: changes the target project
* Body `label`: optional
* Body `allow_fallback`: optional
* Body `allowed_models`: optional list of model ids or brand/\* entries

Worth knowing:

* api\_key and endpoint are validated together before either is applied.
* label and allow\_fallback update on their own, without a credential check.

### Rotate a single-string provider key

**Who can do this:** An organization member holding provider\_keys:write.

`PATCH /v1/provider-keys/generic/{pk_id}`

* Auth: User session JWT only
* Permission: `provider_keys:write`
* Body `api_key`: the new key; omit to change metadata only
* Body `label`: optional
* Body `allow_fallback`: optional
* Body `allowed_models`: optional list of model ids or brand/\* entries

Worth knowing:

* This route serves only keys registered through POST /v1/provider-keys/\{provider}; anything else is a 422.

### Update or repoint a provider key

**Who can do this:** A signed-in member of the organization, acting on their own account's credentials.

`PATCH /v1/provider-keys/{pk_id}`

* Auth: User session JWT only
* Body `secret_ref`: a new Secret Manager version resource name; this is how the credential is rotated
* Body `label`: optional
* Body `is_active`: optional
* Body `allow_fallback`: optional
* Body `allowed_models`: optional list of model ids or brand/\* entries

Worth knowing:

* secret\_ref is bound to the KEY's owner, not the caller, so an org admin rotating a member's key must use that member's namespace.
* The cached secret is evicted at once when secret\_ref changes; keeping the path and publishing a new secret version waits for the TTL.
* Activating a key deactivates every other key of the same owner for that provider, so `{"is_active": true}` is a switch between them, not an addition.

### Rotate an OpenAI key

**Who can do this:** An organization member holding provider\_keys:write.

`PATCH /v1/provider-keys/openai/{pk_id}`

* Auth: User session JWT only
* Permission: `provider_keys:write`
* Body `api_key`: the new key; omit to change metadata only
* Body `label`: optional
* Body `allow_fallback`: optional
* Body `allowed_models`: optional list of model ids or brand/\* entries

Worth knowing:

* The key must already be an OpenAI BYOK key, or the call is a 422.

### Rotate a Vertex AI service account

**Who can do this:** An organization member holding provider\_keys:write.

`PATCH /v1/provider-keys/vertex/{pk_id}`

* Auth: User session JWT only
* Permission: `provider_keys:write`
* Body `private_key`: rotates the credential; send any other service-account field you want changed with it
* Body `region`: optional
* Body `label`: optional
* Body `allow_fallback`: optional
* Body `allowed_models`: optional list of model ids or brand/\* entries

Worth knowing:

* private\_key alone starts a rotation: every other service-account field you omit falls back to the value already stored.
* Without private\_key only label, region, allow\_fallback and allowed\_models are applied; the other service-account fields are ignored.

### Change a member's role or limits

**Who can do this:** An organization member holding members:write at organization scope.

`PATCH /v1/orgs/current/members/{target_user_id}`

* Auth: User session JWT only
* Permission: `members:write`
* Body `role`: admin, member or viewer; defaults to member - owner cannot be invited or assigned, use POST /v1/orgs/current/transfer-ownership
* Body `member_rpm_limit`: optional
* Body `member_rpd_limit`: optional
* Body `member_tpm_limit`: optional
* Body `member_spend_cap`: optional
* Body `allowed_models`: optional list of model ids or brand/\* entries
* Body `blocked_models`: optional; deny wins

Worth knowing:

* The role field is the built-in one; custom roles are set with PUT /v1/orgs/current/members/\{target\_user\_id}/roles.
* The owner's own row accepts a model-policy edit only; anything touching role or limits is a 403.

### Change a custom organization role

**Who can do this:** An organization owner or admin who may manage roles.

`PATCH /v1/orgs/current/roles/{role_id}`

* Auth: User session JWT only
* Permission: `org:read, plus the right to manage roles`
* Body `name`: optional
* Body `scope`: self, team or org
* Body `permissions`: REPLACES the whole set; omit to leave it alone

Worth knowing:

* Everyone holding the role gains whatever this adds, so it widens live access.
* The reach guard runs on the RESULTING set and scope, not the delta, so a modest role cannot be created and then widened past what the caller holds.
* slug is deliberately not updatable: clients refer to the role by it.

### Change a team member's role or limits

**Who can do this:** A caller holding members:write on that team.

`PATCH /v1/orgs/current/teams/{team_id}/members/{target_user_id}`

* Auth: User session JWT only
* Permission: `members:write, team-scoped`
* Body `role`: admin, member or viewer
* Body `member_rpm_limit`: optional
* Body `member_rpd_limit`: optional
* Body `member_tpm_limit`: optional
* Body `member_spend_cap`: optional

Worth knowing:

* Promoting to the team's admin role widens what that person may do inside the team.
* This is the team role, which is separate from the organization role on PATCH /v1/orgs/current/members/\{target\_user\_id}.

## Not possible over MCP

MCP is a request-and-response protocol and these surfaces are streams. Use the REST or WebSocket API directly.

### Live full-duplex session

**Who can do this:** Any caller with an rsk\_ key carrying the realtime:write scope.

`WSS /v1/live?model=<model-id>`

* Auth: Sec-WebSocket-Protocol: openai-realtime, Bearer rsk\_YOUR\_KEY; fallback ?api\_key=rsk\_YOUR\_KEY
* Permission: `realtime:write`

Worth knowing:

* Errors arrive as a JSON text frame with `"type": "error"` before the close.

### Realtime speech-to-speech session

**Who can do this:** Any caller with an rsk\_ key carrying the realtime:write scope.

`WSS /v1/realtime?model=<model-id>`

* Auth: Sec-WebSocket-Protocol: openai-realtime, Bearer rsk\_YOUR\_KEY; fallback ?api\_key=rsk\_YOUR\_KEY
* Permission: `realtime:write`

Worth knowing:

* Errors arrive as a JSON text frame with `"type": "error"` before the close.
* The close code is deliberately generic (1000 even for an auth failure): read error.code, not the close code.

### Streaming speech-to-text over WebSocket

**Who can do this:** Any caller with an rsk\_ key carrying the realtime:write scope.

`WSS /v1/audio/transcriptions/realtime?model=<model-id>`

* Auth: Sec-WebSocket-Protocol: Bearer rsk\_YOUR\_KEY, or ?api\_key=rsk\_YOUR\_KEY
* Permission: `realtime:write`

Worth knowing:

* Errors arrive as a JSON text frame with `"message_type": "error"`, then a normal close (1000).

### Streaming text-to-speech over WebSocket

**Who can do this:** Any caller with an rsk\_ key carrying the realtime:write scope.

`WSS /v1/audio/speech/stream/{voice_id}?model_id=<model-id>`

* Auth: Sec-WebSocket-Protocol: Bearer rsk\_YOUR\_KEY, or ?api\_key=rsk\_YOUR\_KEY
* Permission: `realtime:write`

Worth knowing:

* Auth and scope failures arrive as a JSON text frame with `"type": "error"`, then a normal close (1000).

### Token streaming for chat and responses

**Who can do this:** Any caller with an rsk\_ key.

`POST /v1/chat/completions`

* Auth: Authorization: Bearer rsk\_YOUR\_KEY
* Body `stream`: true

Worth knowing:

* POST /v1/responses takes the same stream flag.

## Not available as tools yet

These work today through the REST API. They are not MCP tools yet.

### Customer API surface not yet exposed as tools

**Who can do this:** Any holder of an rsk\_ key with the matching scope.

Worth knowing:

* Covers audio TTS and STT, video, batches, memories, playground, usage, providers, errors, model detail, file delete and embed, /v1/messages, responses retrieve, template versions and catalog, and GET /v1/api-versions.
* There is no MCP tool for these yet; call the REST API directly with an rsk\_ key, which works today.
* These are planned as tools; until they ship, the REST API is the way to do them.

### Management plane not yet exposed as tools

**Who can do this:** An organization member with the relevant permission, using a mak\_ admin key or a user session. Three exceptions: /v1/admin-keys is user-session only, because a mak\_ bearer fails JWT verification and is refused before any handler runs; /v1/audit-logs takes a dashboard session or an rsk\_ key, never a mak\_ one; and GET /alerts/verify-email is authorised by the one-time token in the link it is reached from, not by a credential of yours.

Worth knowing:

* Covers key listing, updates and deletion under /v1/keys (not its POST), listing, reading and revoking mak\_ keys under /v1/admin-keys, /alerts, /v1/webhooks/deliveries, /v1/routing-policy-templates and /v1/audit-logs.
* There is no MCP tool for these yet; call the REST API directly with a mak\_ admin key or a user session JWT, which works today.
* These are planned as tools; until they ship, the REST API is the way to do them.

### User and organization plane not yet exposed as tools

**Who can do this:** A signed-in user, with the role the action needs in their organization.

Worth knowing:

* Covers /v1/orgs, /v1/provider-keys, billing and checkout, auto-recharge, invitations, settings and the rest of the user session surface.
* There is no MCP tool for these yet; call the REST API directly with a user session JWT, which works today.
* These are planned as tools; until they ship, the REST API is the way to do them.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.