Complete a one-time OAuth exchange
const url = 'https://api.katara.com/katara/v1/orgs/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/environments/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/tool-credentials/oauth/authorizations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/complete';const options = { method: 'POST', headers: { 'X-Katara-CSRF': '1', Authorization: 'Bearer <token>', 'Content-Type': 'application/json' }, body: '{"state":"example","issuer":"https://example.com","code_base64":"example"}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.katara.com/katara/v1/orgs/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/environments/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/tool-credentials/oauth/authorizations/2489E9AD-2EE2-8E00-8EC9-32D5F69181C0/complete \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --header 'X-Katara-CSRF: 1' \ --data '{ "state": "example", "issuer": "https://example.com", "code_base64": "example" }'Requires the current human session and exact environment authority. Begin and activate require caller idempotency keys; Complete uses the durable one-use authorization ID and no idempotency header. No automatic retries or provider exchange replay. The Start response pins organization, environment, mode, reset generation and profile before navigation. Never persist or log its URL/state, callback code, original sensitive error or token response. After unknown completion inspect Review. oauth_exchange_uncertain (409) requires inspection, not retry; oauth_authorization_rejected (403) requires a new authorization. Activation requires explicit review of the verified account digest. Tokens never leave protected service storage. All routes reject query parameters. Begin requires an explicitly reviewed authorization_expires_at, strictly future and within the enrolled profile max_authorization_seconds. Start and Review echo that immutable authority deadline. The separate expires_at is the 10-minute setup/review window. Serialized private token refresh never extends the connection authority deadline.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Path Parameters
Section titled “Path Parameters”Header Parameters
Section titled “Header Parameters”Browser cookie mutations require value 1 and an allowed Origin. Session bearer clients may omit this header.
Required for cookie-authenticated changes. Use the UUID of the account that loaded the application. A different current cookie account returns account_changed before the handler runs. Session bearer and API key clients do not require this header.
Request Bodyrequired
Section titled “Request Bodyrequired”object
Ephemeral authorization code, decoded 1–4096 printable non-space ASCII bytes. Never persist, log or automatically replay the exchange.
Examplegenerated
{ "state": "example", "issuer": "https://example.com", "code_base64": "example"}Responses
Section titled “Responses”OAuth metadata; no access or refresh tokens.
object
object
object
object
object
object
Example
{ "mode": "test", "owner_kind": "user", "status": "pending", "account": { "mode": "test" }}Headers
Section titled “Headers”Account_changed: reload and review with the signed-in account.
default
Section titled “default”Request error
object
object
Stable; branch on it. Any operation can answer invalid_request, with param naming the refused field when there is one; human_session_required, when an API key, service account or workload calls an operation only a signed-in person may perform; reauthentication_required, when a person’s sign-in is too old for the operation; permission_denied; route_not_found and method_not_allowed, when no operation matches the path or method; and feature_unavailable, when the operation’s service is not enabled on this deployment.
The request field a refusal is about, such as the agent_id or run_id query parameter; null when the refusal is not about one field.
Example
{ "error": { "action": "sign_in" }}