Check one member of a platform key pool with the vendor
POST /v1/platform/credentials/{provider}/{key_id}/verify
| Property | Value |
|---|---|
| Operation | verify_platform_credential |
| Group | Platform |
| Scope | platform:write |
| Route class | control |
| Idempotency | Idempotency-Key accepted: a retry with the same key replays the first answer |
| Audit | Audited platform.credential.verify (mutation) |
| Released in | 1.41.0 |
| Phase 0 host | Served (the hosted api pins 1.65.0) |
Asks the vendor whether it accepts the stored key of one active member of the Provider's key pool and, where the vendor offers an account request, what the account behind it can serve (1.41.0, boards #121 and #135). A key the vendor refuses answers 200 with ok false and account null, and the check changes nothing else; a vendor that does not answer is dependency_unavailable. When the check reads the account, the api stores the reading as the credential's account in the transaction of the Audit event; a refused key or a failed account request leaves the stored account as it was. The secret is never returned, logged or written to the Audit event, which names the Provider, the version and the outcome. A revoked member, or one of another Provider, is not_found. The check never disables a member; an operator does that with PATCH.
Request
Set VOCAL_API to the base URL of your API and VOCAL_API_KEY to an API key with the platform:write scope (Authentication and keys). Replace each placeholder, such as agt_... or <name>, with your own value.
curl -X POST "$VOCAL_API/v1/platform/credentials/mock/plk_.../verify" \
-H "Authorization: Bearer $VOCAL_API_KEY" \
-H "Idempotency-Key: $(uuidgen)"const response = await fetch(`${process.env.VOCAL_API}/v1/platform/credentials/mock/plk_.../verify`, {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.VOCAL_API_KEY}`,
'Idempotency-Key': crypto.randomUUID(),
},
});
console.log(response.status, await response.text());import os
import uuid
import requests
response = requests.post(
f"{os.environ['VOCAL_API']}/v1/platform/credentials/mock/plk_.../verify",
headers={
"Authorization": f"Bearer {os.environ['VOCAL_API_KEY']}",
"Idempotency-Key": str(uuid.uuid4()),
},
)
print(response.status_code, response.text)Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
provider | path | ProviderId | yes | A Provider: a vendor or in-process model behind a stage. The provider catalog says which stages each serves and whether it is available. From 1.38.0 openai is deprecated (workspace ADR 0085): its descriptors read deprecated, a deprecated Provider still resolves, and the id is kept until a major release; deepseek is new. From 1.53.0 amazon_titan serves embeddings, reserved until its adapter is built. |
key_id | path | PlatformCredentialId | yes | The id of a platform credential, one member of a Provider key pool: plk_ and the row's UUIDv7 in 26 Crockford base32 characters. Opaque and safe to log. |
idempotency-key | header | string | no | A client-chosen key, kept 24 hours per Organization, environment and route. A replay returns the stored response. |
Responses
| Status | Content type | Shape | Error codes |
|---|---|---|---|
200 | application/json | CredentialVerifyResult | |
400 | application/json | ErrorEnvelope | invalid_request |
401 | application/json | ErrorEnvelope | unauthenticated |
403 | application/json | ErrorEnvelope | forbidden |
404 | application/json | ErrorEnvelope | not_found |
409 | application/json | ErrorEnvelope | idempotency_in_progress, idempotency_key_reused |
429 | application/json | ErrorEnvelope | rate_limited |
500 | application/json | ErrorEnvelope | internal_error |
503 | application/json | ErrorEnvelope | dependency_unavailable |
Fields of the 200 answer
The shape is CredentialVerifyResult.
| Field | Type | Required | Description |
|---|---|---|---|
account | VendorAccountUsage or null | yes | The account reading the check took; null when the key was refused, when the vendor has no account request or when the account request failed. |
checked_at | Timestamp | yes | When the api asked the vendor. |
ok | boolean | yes | True when the vendor accepted the key. It says nothing about quota: read account.status for that. |