---
title: "Poll owner consent and exchange an approval for a clone-scoped grant token."
method: POST
path: "/v1/exchange_external_authorization"
tags: ["External Authorization"]
---

# Poll owner consent and exchange an approval for a clone-scoped grant token.

`POST /v1/exchange_external_authorization`

## Request

- Base URL: `https://partner.mindupload.app`
- URL: `https://partner.mindupload.app/v1/exchange_external_authorization`
- Auth: API key in header `X-Partner-Key`

Poll no faster than `poll_interval`. `pending`, `slow_down`, and `denied` are successful protocol states without a token. After approval, repeated calls with the same unexpired device code return the same grant token, which makes a lost response safe to retry. On success the response includes `clone_ids` and `clone_nicknames` (id → display name) so partners can label linked clones immediately without a prior invoke.

## Request body

- object
  - `preferred_language` string, nullable: BCP-47-ish language code (e.g. 'en', 'zh-cn') for localized messages.
  - `device_code` string, required: Short-lived high-entropy secret used only to poll and exchange this request.

## Response `200`

Result envelope — check the success field.

- object
  - `success` boolean, required: Whether the call succeeded.
  - `error_message` string, nullable, required: Human-readable reason when success is false.
  - `error_code` string
  - `status` 'pending' | 'slow_down' | 'denied' | 'expired' | 'revoked' | 'exchanged', nullable, required: Current authorization or invocation lifecycle state.
  - `access_token` string, nullable, required: Opaque grant token accepted only by grant inspection and external clone invocation; store it as a secret and never expose it to users.
  - `refresh_token` string, nullable, required: Opaque grant-lifetime token used only with refresh_external_authorization; store it as a secret.
  - `token_type` 'Bearer', nullable, required: Authorization token type.
  - `grant_id` string, nullable, required: Stable grant identifier used by the owner-facing revocation surface.
  - `scopes` string[], nullable, required: Capabilities approved by the owner.
  - `clone_ids` string[], nullable, required: AI consciousness resources selected by the owner.
  - `clone_nicknames` object, nullable, required: Map of granted clone id to plaintext display nickname so partners can label linked clones immediately after approval.
  - `access_token_expires_at` integer, nullable, required: UNIX timestamp after which the short-lived access token must be refreshed.
  - `expires_at` integer, nullable, required: UNIX timestamp when this resource or capability expires.
  - `poll_interval` integer, nullable, required: Minimum seconds to wait between exchange polls.

## Other responses

- `400`: Invalid request payload.
- `401`: Missing or invalid partner key.
- `403`: Partner is not authorized for this operation.
- `429`: Rate limit exceeded — retry later.
- `500`: Internal server error.

---

[API](https://skmtc.dev/mindupload/apis/mind-upload-partner-api.md) · [All operations](https://skmtc.dev/mindupload/apis/mind-upload-partner-api/llms.txt) · [OpenAPI document](https://skmtc.dev/mindupload/apis/mind-upload-partner-api/revisions/0371bdf78533?raw)
