---
title: "Verify Authorization Token"
method: POST
path: "/v1/authorization_tokens/verify"
tags: ["Authorization Tokens"]
---

# Verify Authorization Token

`POST /v1/authorization_tokens/verify`

Verify an Authorization Token by its `code` value.

This endpoint is used by DAFs in the **Donor-Initiated Verification** flow: when a donor presents the `code` they received from DAFpay (via email after submitting a Grant Request), the DAF calls this endpoint with the `code` to confirm the donor's identity.

On success:
- The Authorization Token transitions to `verified`.
- The linked Donor Account is automatically transitioned to `approved` if it is currently `pending`.
- The full Donor Account is returned (including the `id` you can use to call subsequent endpoints).

Codes are only valid until the token's `expires_at` — **30 days** after creation by default (configurable via `expires_in` on [Create Authorization Token](/api/authorization-tokens/create), 60 seconds to 90 days). After that point, the token's status becomes `expired` and verification will fail. If the donor's code has expired, prompt them to submit a new Grant Request — DAFpay will issue and email a fresh code automatically.

<Warning>
Error handling:
- If the `code` is unknown, expired, revoked, or already verified, the request will return status `404 Not Found` or `410 Gone` to avoid leaking information about valid codes. Expired codes are intentionally indistinguishable from other invalid codes in the response — surface a generic "code is invalid or has expired" message to the donor and ask them to request a new code.
- If the linked Donor Account has already been rejected, the request will return status `409 Conflict`.
- To prevent brute-force attacks, this endpoint enforces strict per-DAF rate limits. Repeated failures will return status `429 Too Many Requests`.
</Warning>

## Request body

- object
  - `code` string, required — The token's secret code value as provided by the donor. Verification is case-insensitive and tolerant of whitespace and dashes.
  - `external_id` string — The DAF's internal identifier for this Donor Account. If provided, will be set on the Donor Account as part of the verification. Maximum length: 255 characters.

## Response `200`

The token was successfully verified and the Donor Account was approved.

- DonorAccount — A Donor Account represents a DAFpay donor identity at a DAF. Donor Accounts are the bridge between a donor's verified DAFpay identity (email, profile) and the donor's record at the DAF. An Account must reach `approved` status — via an [Authorization Token](/api/authorization-tokens) — before its Grant Requests can be processed. A Donor Account may optionally have one or more [Giving Pools](/api/giving-pools) associated with it (see [Giving Pool](/api/giving-pools)). The relationship is many-to-one from `GivingPool` to `DonorAccount` — each Giving Pool belongs to exactly one Donor Account. There are two flows for how an Account reaches `approved`: - **Donor-Initiated Verification**: After a donor submits a Grant Request, DAFpay issues a one-time [Authorization Token](/api/authorization-tokens) and emails the `code` to the donor. The donor provides the code to the DAF, who calls [Verify Authorization Token](/api/authorization-tokens/verify) to approve the account. - **DAF-Initiated Setup**: The DAF creates the Donor Account and an Authorization Token in advance (e.g. when a donor opts in via the DAF portal). The donor enters the token's `code` into DAFpay during profile setup, automatically approving the account. See the [Donor Accounts overview](/guides/dafpay/donor-accounts/overview) for a full discussion of these flows.
  - `id` string, required — The unique identifier for this object.
  - `status` 'pending' | 'approved' | 'rejected', required — The status of a [Donor Account](/api/donor-accounts). * `pending`: The Donor Account has been created but the DAF has not yet approved or rejected it. * `approved`: The DAF has verified the donor's identity and Grants from this account can be processed. * `rejected`: The DAF has rejected the Donor Account. Grants from this account will not be processed.
  - `donor` object, required — The donor's identity and profile information.
    - `email` string, required — The donor's email. This is the donor's verified identifier — DAFpay verifies ownership via an email verification flow before a Donor Account is created.
    - `first_name` string, nullable — The donor's first name as captured during DAFpay profile setup. May be null for Donor Accounts created via [Create Donor Account](/api/donor-accounts/create) before the donor has authenticated.
    - `last_name` string, nullable — The donor's last name as captured during DAFpay profile setup. May be null for Donor Accounts created via [Create Donor Account](/api/donor-accounts/create) before the donor has authenticated.
    - `phone` string, nullable — The donor's phone number as captured during DAFpay profile setup. <Note> DAFpay does not currently verify ownership of the phone number. Treat this field as donor-asserted information. </Note>
  - `external_id` string, nullable — The DAF's internal identifier for this Donor Account. Can be set on creation or via [Update Donor Account](/api/donor-accounts/update) to link the DAFpay Donor Account to the donor's record in the DAF's own systems.
  - `approval` object, nullable — Details about the approval decision. Present when `status` is `approved`; otherwise `null`.
    - `approved_at` string, date-time — Time when the Donor Account was approved. Expressed in RFC 3339 format.
    - `approved_by` string — Identifier of the actor that approved this Donor Account. For DAF-initiated approvals, this is the DAF's API key principal. For automatic approvals via token verification, this is `system:authorization_token`.
  - `rejection` object, nullable — Details about the rejection decision. Present when `status` is `rejected`; otherwise `null`.
    - `rejected_at` string, date-time — Time when the Donor Account was rejected. Expressed in RFC 3339 format.
    - `rejected_by` string — Identifier of the actor that rejected this Donor Account. For DAF-initiated rejections, this is the DAF's API key principal.
    - `rejection_reason` string — A human-readable reason provided by the DAF when rejecting the Donor Account.
  - `disabled` boolean — Whether this Donor Account is currently disabled. A disabled Donor Account remains `approved` but cannot submit new Grant Requests — call [Enable Donor Account](/api/donor-accounts/enable) to re-enable it. Disabling is only available for accounts in `approved` status.
  - `created_at` string, date-time, required — Time when this object was created. Expressed in RFC 3339 format.
  - `updated_at` string, date-time, required — Time when this object was last updated. Expressed in RFC 3339 format.
  - `metadata` object — A map of arbitrary string keys and values to store information about the object.

## Other responses

- `400` — The request is invalid or contains invalid parameters
- `401` — Unauthorized. The request is missing the security (OAuth2 Bearer token) requirements and the server is unable to verify the identify of the caller.
- `403` — Access denied
- `404` — Resource Not Found
- `409` — Resource Conflicts
- `410` — Resource Gone or Expired
- `500` — Internal Server Error

---

[API](https://skmtc.net/chariot-giving/apis/specs.md) · [All operations](https://skmtc.net/chariot-giving/apis/specs/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/chariot-giving/specs/revisions/8446023e02fb/schema)
