{
  "openapi": "3.1.0",
  "info": {
    "title": "XipID API",
    "version": "2026-09-26",
    "summary": "Is the person of record present and consenting, right now.",
    "description": "XipID asks the person of record whether they are present and consent, right now. A brand refers a person by its own reference for them; once they accept, it challenges them by the pairwise identifier their acceptance gave it. XipID texts them a link that carries nothing but a token, they read the request on their own phone and approve it, with a selfie when the brand's policy asks for one, or decline it, and the outcome is posted to the brand's callback URL, signed.\n\n**Agents.** An org's agent calls with a credential of its own, `xid_agent_live_` and 32 characters, where a brand calls with its key. It acts through one of its org's brands: it names a person by the pairwise identifier that brand holds for them, and once the person has delegated their presence to it, its challenge goes out under that brand. Each operation says who may call it, and refuses every other credential, `insufficient_scope`.\n\n**Versions.** Every request may name a version in `Xip-Version`; without one it is answered in the version its org is pinned to, and every answer names the version it is in. A version is the day its contract was fixed.\n\n**Errors.** A refusal is `{\"error\": {...}}` with a `code` to branch on, a sentence for a person, one entry in `details` per problem, the request's id, which `X-Request-Id` names too, and the page that explains the code. A code may carry members of its own.\n\n**Idempotency.** Every POST that makes or changes something takes an `Idempotency-Key`; a retry under it is answered what the first request was, for 24 hours.\n\n**Lists.** A list answers a page of items with cursors either way; `starting_after` and `ending_before` take them back.\n\n**Limits.** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Growth.** An answer may gain a member, and an enum a value, within a version: read what you know and carry the rest through. Every instant is RFC 3339 in UTC with milliseconds.",
    "contact": {
      "name": "XipID",
      "url": "https://xipid.org",
      "email": "help@xipid.org"
    }
  },
  "servers": [
    {
      "url": "https://api.xipid.org"
    }
  ],
  "security": [
    {
      "apiKey": []
    },
    {
      "agentCredential": []
    }
  ],
  "tags": [
    {
      "name": "Challenges",
      "description": "A request the person of record approves or declines on their own phone, and how it closed."
    },
    {
      "name": "Subjects",
      "description": "The people a brand refers by its own reference for them, linked once they accept, and the face a selfie of theirs is matched to."
    },
    {
      "name": "Events",
      "description": "The outcomes as they were posted to the brand's callback URLs, for 30 days."
    },
    {
      "name": "Delegations",
      "description": "An agent's requests that a person delegate their presence to it, which the person accepts or declines on their XipID."
    }
  ],
  "paths": {
    "/challenges": {
      "post": {
        "operationId": "createChallenge",
        "tags": [
          "Challenges"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "agentCredential": []
          }
        ],
        "summary": "Create a challenge",
        "description": "Asks a person the brand linked, named by the pairwise identifier their referral answered, to approve a request. XipID texts them a link before it answers, and posts the outcome to the callback URL when the challenge closes. The callback URL is https and resolves to public addresses alone, or the challenge is refused before anything is made; XipID checks it again at each delivery and never follows a redirect. A retry under the same `Idempotency-Key` is answered the same challenge, its `link` `null`: the link is shown once. An agent of the brand's org creates one for a person who delegated their presence to it, naming them by the pairwise identifier one of its org's brands holds for them: the challenge goes out under that brand, by the brand's text, and its outcome, signed with the brand's secrets, names the agent. Without a live delegation it is refused, `consent_missing`, before anything is sent.\n\n**Scope:** any live key of the brand, or any live credential of an agent.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`. Each challenge is a text: at most 5 an hour and 20 a day reach one number whoever asks, and one org's brands ask for at most 600 an hour and 10,000 a day; past either, the create is refused `429` and makes nothing.\n\n**Idempotency:** takes an `Idempotency-Key`, which it requires: a retry under the same key is answered what the first request was, for 24 hours, and the key sent with another request is refused.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "The operation's key, 1 to 255 characters, best a UUID, in double quotes as a structured field string: a retry of the operation sends it again, and is answered what the first request was, for 24 hours.",
            "schema": {
              "type": "string",
              "maxLength": 512
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateChallenge"
              },
              "example": {
                "subject": {
                  "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d"
                },
                "request": {
                  "type": "wire",
                  "title": "Wire to Ridgeline Fabrication",
                  "summary": "The first payment on invoice 2291.",
                  "money": {
                    "amount_minor": 4500000,
                    "currency": "USD"
                  },
                  "counterparty": "Ridgeline Fabrication",
                  "reference": "INV-2291",
                  "requested_at": "2026-11-19T13:04:00-05:00"
                },
                "policy": {
                  "checks": [
                    "liveness",
                    "face_match"
                  ],
                  "expires_in_seconds": 600
                },
                "callback": {
                  "url": "https://acme-bank.example/xipid/outcomes"
                },
                "metadata": {
                  "branch": "downtown"
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The challenge, with the link the person was texted, which no other answer shows. `Location` names it.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/ChallengeCreated"
                },
                "example": {
                  "id": "01JD2R5W8Y3K6M9P2S5V8X1Z4B",
                  "brand_id": "01JD2R1A3C5E7G9J1K3M5N7P9Q",
                  "status": "sent",
                  "subject": {
                    "id": "01JD2R2B4D6F8H0J2K4M6N8P0Q",
                    "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d",
                    "reference": "acct_4417"
                  },
                  "request": {
                    "type": "wire",
                    "title": "Wire to Ridgeline Fabrication",
                    "summary": "The first payment on invoice 2291.",
                    "money": {
                      "amount_minor": 4500000,
                      "currency": "USD"
                    },
                    "counterparty": "Ridgeline Fabrication",
                    "reference": "INV-2291",
                    "requested_at": "2026-11-19T18:04:00.000Z"
                  },
                  "policy": {
                    "checks": [
                      "liveness",
                      "face_match"
                    ],
                    "allow_decline": true,
                    "allow_note": true,
                    "expires_in_seconds": 600
                  },
                  "callback": {
                    "url": "https://acme-bank.example/xipid/outcomes"
                  },
                  "metadata": {
                    "branch": "downtown"
                  },
                  "checks": [],
                  "text": {
                    "status": "sent"
                  },
                  "created_at": "2026-11-19T18:04:00.512Z",
                  "sent_at": "2026-11-19T18:04:01.204Z",
                  "expires_at": "2026-11-19T18:14:00.512Z",
                  "link": "https://app.xipid.org/c/Ab3dEf6hJk9mNp2qRs5tUv"
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_missing`, `parameter_invalid`, `parameter_unknown`, `idempotency_key_missing`, `version_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_missing": {
                    "summary": "The request lacks a required parameter.",
                    "value": {
                      "error": {
                        "code": "parameter_missing",
                        "message": "The request lacks a required parameter.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "required",
                            "message": "Required."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_missing"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "idempotency_key_missing": {
                    "summary": "This route requires an Idempotency-Key header.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_missing",
                        "message": "This route requires an Idempotency-Key header.",
                        "details": [
                          {
                            "path": "header.idempotency-key",
                            "code": "required",
                            "message": "Required."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_missing"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The resource's state refuses the request. Its code is one of `idempotency_key_in_use`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_in_use": {
                    "summary": "The first request with this Idempotency-Key is still running.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_in_use",
                        "message": "The first request with this Idempotency-Key is still running.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_in_use"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "A rule refuses the well-formed request. Its code is one of `idempotency_key_reused`, `subject_unlinked`, `consent_missing`, `channel_unavailable`, `reference_face_missing`, `callback_url_refused`, `text_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "summary": "This Idempotency-Key was used for a different request.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_reused",
                        "message": "This Idempotency-Key was used for a different request.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_reused"
                      }
                    }
                  },
                  "subject_unlinked": {
                    "summary": "The pairwise identifier names no person linked to this brand, or to a brand of this agent's org.",
                    "value": {
                      "error": {
                        "code": "subject_unlinked",
                        "message": "The pairwise identifier names no person linked to this brand, or to a brand of this agent's org.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/subject_unlinked",
                        "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d"
                      }
                    }
                  },
                  "consent_missing": {
                    "summary": "The person has not granted this brand, or this agent, their presence.",
                    "value": {
                      "error": {
                        "code": "consent_missing",
                        "message": "The person has not granted this brand, or this agent, their presence.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/consent_missing",
                        "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d"
                      }
                    }
                  },
                  "channel_unavailable": {
                    "summary": "The person has no phone XipID may text.",
                    "value": {
                      "error": {
                        "code": "channel_unavailable",
                        "message": "The person has no phone XipID may text.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/channel_unavailable",
                        "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d"
                      }
                    }
                  },
                  "reference_face_missing": {
                    "summary": "The person has no face on file.",
                    "value": {
                      "error": {
                        "code": "reference_face_missing",
                        "message": "The person has no face on file.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/reference_face_missing",
                        "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d"
                      }
                    }
                  },
                  "callback_url_refused": {
                    "summary": "No outcome can be posted to that callback URL.",
                    "value": {
                      "error": {
                        "code": "callback_url_refused",
                        "message": "No outcome can be posted to that callback URL.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/callback_url_refused"
                      }
                    }
                  },
                  "text_failed": {
                    "summary": "The provider refused the text.",
                    "value": {
                      "error": {
                        "code": "text_failed",
                        "message": "The provider refused the text.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/text_failed",
                        "challenge_id": "01JD2R5W8Y3K6M9P2S5V8X1Z4B",
                        "provider": "twilio",
                        "provider_code": 21211
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "A service XipID depends on failed. Its code is one of `upstream_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_error": {
                    "summary": "A service XipID depends on failed.",
                    "value": {
                      "error": {
                        "code": "upstream_error",
                        "message": "A service XipID depends on failed.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          },
          "504": {
            "description": "A service XipID depends on did not answer in time. Its code is one of `upstream_timeout`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_timeout": {
                    "summary": "A service XipID depends on did not answer in time.",
                    "value": {
                      "error": {
                        "code": "upstream_timeout",
                        "message": "A service XipID depends on did not answer in time.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_timeout"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/challenges/{id}": {
      "get": {
        "operationId": "getChallenge",
        "tags": [
          "Challenges"
        ],
        "security": [
          {
            "apiKey": []
          },
          {
            "agentCredential": []
          }
        ],
        "summary": "Read a challenge",
        "description": "The challenge as it stands, and as it closed once it has: its status, its checks and what became of its text. Each read is recorded as the brand's read, with the key that made it, and the person sees on their XipID how many times the brand read. An agent reads the challenges it created alone, and each of its reads is recorded as its own, with the credential that made it.\n\n**Scope:** any live key of the brand, or any live credential of an agent.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** a read, safe to repeat.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "XipID's id for the challenge.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "responses": {
          "200": {
            "description": "The challenge as it stands.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Challenge"
                },
                "example": {
                  "id": "01JD2R5W8Y3K6M9P2S5V8X1Z4B",
                  "brand_id": "01JD2R1A3C5E7G9J1K3M5N7P9Q",
                  "status": "verified",
                  "subject": {
                    "id": "01JD2R2B4D6F8H0J2K4M6N8P0Q",
                    "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d",
                    "reference": "acct_4417",
                    "tier": 1
                  },
                  "request": {
                    "type": "wire",
                    "title": "Wire to Ridgeline Fabrication",
                    "summary": "The first payment on invoice 2291.",
                    "money": {
                      "amount_minor": 4500000,
                      "currency": "USD"
                    },
                    "counterparty": "Ridgeline Fabrication",
                    "reference": "INV-2291",
                    "requested_at": "2026-11-19T18:04:00.000Z"
                  },
                  "policy": {
                    "checks": [
                      "liveness",
                      "face_match"
                    ],
                    "allow_decline": true,
                    "allow_note": true,
                    "expires_in_seconds": 600
                  },
                  "callback": {
                    "url": "https://acme-bank.example/xipid/outcomes"
                  },
                  "metadata": {
                    "branch": "downtown"
                  },
                  "checks": [
                    {
                      "check": "liveness",
                      "passed": true,
                      "score": 0.98,
                      "mode": "movement_and_light",
                      "checked_at": "2026-11-19T18:06:41.090Z"
                    },
                    {
                      "check": "face_match",
                      "passed": true,
                      "score": 0.99,
                      "checked_at": "2026-11-19T18:06:41.090Z"
                    }
                  ],
                  "text": {
                    "status": "delivered"
                  },
                  "created_at": "2026-11-19T18:04:00.512Z",
                  "sent_at": "2026-11-19T18:04:01.204Z",
                  "expires_at": "2026-11-19T18:14:00.512Z",
                  "consent": {
                    "agreed_at": "2026-11-19T18:06:12.377Z",
                    "notice_version": "request-selfie-2026-11-02"
                  },
                  "opened_at": "2026-11-19T18:05:30.861Z",
                  "decided_at": "2026-11-19T18:06:41.090Z"
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_invalid`, `parameter_unknown`, `version_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Nothing the credential may read goes by that id. Its code is one of `resource_not_found`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "No such resource.",
                    "value": {
                      "error": {
                        "code": "resource_not_found",
                        "message": "No such resource.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/resource_not_found"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/challenges/{id}/cancel": {
      "post": {
        "operationId": "cancelChallenge",
        "tags": [
          "Challenges"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Cancel a challenge",
        "description": "Closes an open challenge as `canceled`: the page then tells the person the request was withdrawn, and the outcome `challenge.canceled` is posted to the callback URL.\n\n**Scope:** any live key of the brand.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** takes an `Idempotency-Key`, which it requires: a retry under the same key is answered what the first request was, for 24 hours, and the key sent with another request is refused.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "XipID's id for the challenge.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "The operation's key, 1 to 255 characters, best a UUID, in double quotes as a structured field string: a retry of the operation sends it again, and is answered what the first request was, for 24 hours.",
            "schema": {
              "type": "string",
              "maxLength": 512
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "responses": {
          "200": {
            "description": "The challenge, canceled.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Challenge"
                },
                "example": {
                  "id": "01JD2R5W8Y3K6M9P2S5V8X1Z4B",
                  "brand_id": "01JD2R1A3C5E7G9J1K3M5N7P9Q",
                  "status": "canceled",
                  "subject": {
                    "id": "01JD2R2B4D6F8H0J2K4M6N8P0Q",
                    "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d",
                    "reference": "acct_4417"
                  },
                  "request": {
                    "type": "wire",
                    "title": "Wire to Ridgeline Fabrication",
                    "summary": "The first payment on invoice 2291.",
                    "money": {
                      "amount_minor": 4500000,
                      "currency": "USD"
                    },
                    "counterparty": "Ridgeline Fabrication",
                    "reference": "INV-2291",
                    "requested_at": "2026-11-19T18:04:00.000Z"
                  },
                  "policy": {
                    "checks": [
                      "liveness",
                      "face_match"
                    ],
                    "allow_decline": true,
                    "allow_note": true,
                    "expires_in_seconds": 600
                  },
                  "callback": {
                    "url": "https://acme-bank.example/xipid/outcomes"
                  },
                  "metadata": {
                    "branch": "downtown"
                  },
                  "checks": [],
                  "text": {
                    "status": "sent"
                  },
                  "created_at": "2026-11-19T18:04:00.512Z",
                  "sent_at": "2026-11-19T18:04:01.204Z",
                  "expires_at": "2026-11-19T18:14:00.512Z",
                  "decided_at": "2026-11-19T18:05:02.140Z"
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_invalid`, `parameter_unknown`, `idempotency_key_missing`, `version_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "idempotency_key_missing": {
                    "summary": "This route requires an Idempotency-Key header.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_missing",
                        "message": "This route requires an Idempotency-Key header.",
                        "details": [
                          {
                            "path": "header.idempotency-key",
                            "code": "required",
                            "message": "Required."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_missing"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential may not call this operation. Its code is one of `insufficient_scope`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "The credential does not allow this operation.",
                    "value": {
                      "error": {
                        "code": "insufficient_scope",
                        "message": "The credential does not allow this operation.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/insufficient_scope"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Nothing the credential may read goes by that id. Its code is one of `resource_not_found`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "No such resource.",
                    "value": {
                      "error": {
                        "code": "resource_not_found",
                        "message": "No such resource.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/resource_not_found"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The resource's state refuses the request. Its code is one of `idempotency_key_in_use`, `challenge_closed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_in_use": {
                    "summary": "The first request with this Idempotency-Key is still running.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_in_use",
                        "message": "The first request with this Idempotency-Key is still running.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_in_use"
                      }
                    }
                  },
                  "challenge_closed": {
                    "summary": "The challenge is already closed.",
                    "value": {
                      "error": {
                        "code": "challenge_closed",
                        "message": "The challenge is already closed.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/challenge_closed"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "A rule refuses the well-formed request. Its code is one of `idempotency_key_reused`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "summary": "This Idempotency-Key was used for a different request.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_reused",
                        "message": "This Idempotency-Key was used for a different request.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_reused"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/challenges/{id}/deliveries": {
      "get": {
        "operationId": "listDeliveries",
        "tags": [
          "Challenges"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "List a challenge's deliveries",
        "description": "One page of the challenge's deliveries, oldest first: the events posted to its callback URL, each with its last attempt as the receiver answered it, or the class of the failure that got no answer.\n\n**Scope:** any live key of the brand.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** a read, safe to repeat.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "XipID's id for the challenge.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many items the page holds.",
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "starting_after",
            "in": "query",
            "required": false,
            "description": "The page after the item a page's `next_cursor` named.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,512}$"
            }
          },
          {
            "name": "ending_before",
            "in": "query",
            "required": false,
            "description": "The page before the item a page's `previous_cursor` named; not with `starting_after`.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,512}$"
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of deliveries.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/DeliveryPage"
                },
                "example": {
                  "data": [
                    {
                      "id": "01JD2RB7C9E1G3J5K7M9N1P3R5",
                      "challenge_id": "01JD2R5W8Y3K6M9P2S5V8X1Z4B",
                      "event": "challenge.verified",
                      "status": "delivered",
                      "attempts": 1,
                      "last_attempt": {
                        "attempted_at": "2026-11-19T18:06:41.733Z",
                        "duration_ms": 184,
                        "status_code": 200,
                        "response_headers": {
                          "content-type": "application/json"
                        },
                        "response_body": "{\"received\":true}"
                      },
                      "delivered_at": "2026-11-19T18:06:41.917Z",
                      "created_at": "2026-11-19T18:06:41.090Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null,
                  "previous_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_invalid`, `parameter_unknown`, `version_invalid`, `cursor_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  },
                  "cursor_invalid": {
                    "summary": "The cursor is malformed or belongs to another list.",
                    "value": {
                      "error": {
                        "code": "cursor_invalid",
                        "message": "The cursor is malformed or belongs to another list.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/cursor_invalid"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential may not call this operation. Its code is one of `insufficient_scope`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "The credential does not allow this operation.",
                    "value": {
                      "error": {
                        "code": "insufficient_scope",
                        "message": "The credential does not allow this operation.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/insufficient_scope"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Nothing the credential may read goes by that id. Its code is one of `resource_not_found`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "No such resource.",
                    "value": {
                      "error": {
                        "code": "resource_not_found",
                        "message": "No such resource.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/resource_not_found"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "A service XipID depends on failed. Its code is one of `upstream_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_error": {
                    "summary": "A service XipID depends on failed.",
                    "value": {
                      "error": {
                        "code": "upstream_error",
                        "message": "A service XipID depends on failed.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          },
          "504": {
            "description": "A service XipID depends on did not answer in time. Its code is one of `upstream_timeout`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_timeout": {
                    "summary": "A service XipID depends on did not answer in time.",
                    "value": {
                      "error": {
                        "code": "upstream_timeout",
                        "message": "A service XipID depends on did not answer in time.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_timeout"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/challenges/{id}/frames": {
      "get": {
        "operationId": "getFrames",
        "tags": [
          "Challenges"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Read a challenge's frames",
        "description": "The frames XipID kept from the challenge's selfies, for a brand that keeps frames, while they are kept: 90 days from each selfie. A brand may ask for them only over a dispute about the challenge's request, as the notice the person agreed to says. Each retrieval is recorded on the challenge with the key that made it. A challenge with no frames kept is not found.\n\n**Scope:** any live key of the brand.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** a read, safe to repeat.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "XipID's id for the challenge.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "responses": {
          "200": {
            "description": "Every frame still kept.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/CaptureFrames"
                },
                "example": {
                  "challenge_id": "01JD2R5W8Y3K6M9P2S5V8X1Z4B",
                  "frames": [
                    {
                      "capture_id": "01JD2RC8D0F2H4K6M8N0P2Q4S6",
                      "position": 0,
                      "content_type": "image/jpeg",
                      "image": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAA==",
                      "captured_at": "2026-11-19T18:06:40.512Z",
                      "expires_at": "2027-02-17T18:06:40.512Z"
                    }
                  ]
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_invalid`, `parameter_unknown`, `version_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential may not call this operation. Its code is one of `insufficient_scope`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "The credential does not allow this operation.",
                    "value": {
                      "error": {
                        "code": "insufficient_scope",
                        "message": "The credential does not allow this operation.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/insufficient_scope"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Nothing the credential may read goes by that id. Its code is one of `resource_not_found`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "No such resource.",
                    "value": {
                      "error": {
                        "code": "resource_not_found",
                        "message": "No such resource.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/resource_not_found"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "A service XipID depends on failed. Its code is one of `upstream_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_error": {
                    "summary": "A service XipID depends on failed.",
                    "value": {
                      "error": {
                        "code": "upstream_error",
                        "message": "A service XipID depends on failed.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          },
          "504": {
            "description": "A service XipID depends on did not answer in time. Its code is one of `upstream_timeout`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_timeout": {
                    "summary": "A service XipID depends on did not answer in time.",
                    "value": {
                      "error": {
                        "code": "upstream_timeout",
                        "message": "A service XipID depends on did not answer in time.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_timeout"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/events": {
      "get": {
        "operationId": "listEvents",
        "tags": [
          "Events"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "List events",
        "description": "One page of the brand's events of the last 30 days, oldest first: its outcomes as they were posted, of one `type` if it names one, created after, from, before or until the instants it names. A receiver that was down reads them from the `created_at` of the last event it processed.\n\n**Scope:** any live key of the brand.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** a read, safe to repeat.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many items the page holds.",
            "schema": {
              "default": 20,
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            }
          },
          {
            "name": "starting_after",
            "in": "query",
            "required": false,
            "description": "The page after the item a page's `next_cursor` named.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,512}$"
            }
          },
          {
            "name": "ending_before",
            "in": "query",
            "required": false,
            "description": "The page before the item a page's `previous_cursor` named; not with `starting_after`.",
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]{1,512}$"
            }
          },
          {
            "name": "type",
            "in": "query",
            "required": false,
            "description": "Events of this type alone.",
            "schema": {
              "type": "string",
              "enum": [
                "challenge.verified",
                "challenge.check_failed",
                "challenge.declined",
                "challenge.expired",
                "challenge.canceled"
              ],
              "x-enumDescriptions": {
                "challenge.verified": "The person approved and every check passed.",
                "challenge.check_failed": "A check the policy asks for did not pass.",
                "challenge.declined": "The person declined.",
                "challenge.expired": "No decision came before the challenge expired.",
                "challenge.canceled": "The brand canceled the challenge, or its text could not be sent."
              }
            }
          },
          {
            "name": "created_at_gt",
            "in": "query",
            "required": false,
            "description": "Events created after it.",
            "schema": {
              "type": "string",
              "maxLength": 35,
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
            }
          },
          {
            "name": "created_at_gte",
            "in": "query",
            "required": false,
            "description": "Events created at it or after.",
            "schema": {
              "type": "string",
              "maxLength": 35,
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
            }
          },
          {
            "name": "created_at_lt",
            "in": "query",
            "required": false,
            "description": "Events created before it.",
            "schema": {
              "type": "string",
              "maxLength": 35,
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
            }
          },
          {
            "name": "created_at_lte",
            "in": "query",
            "required": false,
            "description": "Events created at it or before.",
            "schema": {
              "type": "string",
              "maxLength": 35,
              "format": "date-time",
              "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "responses": {
          "200": {
            "description": "A page of events.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/EventPage"
                },
                "example": {
                  "data": [
                    {
                      "id": "01JD2RB7C9E1G3J5K7M9N1P3R5",
                      "type": "challenge.verified",
                      "api_version": "2026-09-26",
                      "created_at": "2026-11-19T18:06:41.090Z",
                      "data": {
                        "id": "01JD2R5W8Y3K6M9P2S5V8X1Z4B",
                        "brand_id": "01JD2R1A3C5E7G9J1K3M5N7P9Q",
                        "status": "verified",
                        "subject": {
                          "id": "01JD2R2B4D6F8H0J2K4M6N8P0Q",
                          "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d",
                          "reference": "acct_4417",
                          "tier": 1
                        },
                        "request": {
                          "type": "wire",
                          "title": "Wire to Ridgeline Fabrication",
                          "summary": "The first payment on invoice 2291.",
                          "money": {
                            "amount_minor": 4500000,
                            "currency": "USD"
                          },
                          "counterparty": "Ridgeline Fabrication",
                          "reference": "INV-2291",
                          "requested_at": "2026-11-19T18:04:00.000Z"
                        },
                        "policy": {
                          "checks": [
                            "liveness",
                            "face_match"
                          ],
                          "allow_decline": true,
                          "allow_note": true,
                          "expires_in_seconds": 600
                        },
                        "callback": {
                          "url": "https://acme-bank.example/xipid/outcomes"
                        },
                        "metadata": {
                          "branch": "downtown"
                        },
                        "checks": [
                          {
                            "check": "liveness",
                            "passed": true,
                            "score": 0.98,
                            "mode": "movement_and_light",
                            "checked_at": "2026-11-19T18:06:41.090Z"
                          },
                          {
                            "check": "face_match",
                            "passed": true,
                            "score": 0.99,
                            "checked_at": "2026-11-19T18:06:41.090Z"
                          }
                        ],
                        "text": {
                          "status": "delivered"
                        },
                        "created_at": "2026-11-19T18:04:00.512Z",
                        "sent_at": "2026-11-19T18:04:01.204Z",
                        "expires_at": "2026-11-19T18:14:00.512Z",
                        "consent": {
                          "agreed_at": "2026-11-19T18:06:12.377Z",
                          "notice_version": "request-selfie-2026-11-02"
                        },
                        "opened_at": "2026-11-19T18:05:30.861Z",
                        "decided_at": "2026-11-19T18:06:41.090Z"
                      }
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null,
                  "previous_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_invalid`, `parameter_unknown`, `version_invalid`, `cursor_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  },
                  "cursor_invalid": {
                    "summary": "The cursor is malformed or belongs to another list.",
                    "value": {
                      "error": {
                        "code": "cursor_invalid",
                        "message": "The cursor is malformed or belongs to another list.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/cursor_invalid"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential may not call this operation. Its code is one of `insufficient_scope`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "The credential does not allow this operation.",
                    "value": {
                      "error": {
                        "code": "insufficient_scope",
                        "message": "The credential does not allow this operation.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/insufficient_scope"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "A service XipID depends on failed. Its code is one of `upstream_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_error": {
                    "summary": "A service XipID depends on failed.",
                    "value": {
                      "error": {
                        "code": "upstream_error",
                        "message": "A service XipID depends on failed.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          },
          "504": {
            "description": "A service XipID depends on did not answer in time. Its code is one of `upstream_timeout`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_timeout": {
                    "summary": "A service XipID depends on did not answer in time.",
                    "value": {
                      "error": {
                        "code": "upstream_timeout",
                        "message": "A service XipID depends on did not answer in time.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_timeout"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}": {
      "get": {
        "operationId": "getEvent",
        "tags": [
          "Events"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Read an event",
        "description": "One event of the last 30 days, as it was posted. After 30 days it is deleted, and the challenge holds the outcome.\n\n**Scope:** any live key of the brand.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** a read, safe to repeat.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "XipID's id for the event.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "responses": {
          "200": {
            "description": "The event.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Event"
                },
                "example": {
                  "id": "01JD2RB7C9E1G3J5K7M9N1P3R5",
                  "type": "challenge.verified",
                  "api_version": "2026-09-26",
                  "created_at": "2026-11-19T18:06:41.090Z",
                  "data": {
                    "id": "01JD2R5W8Y3K6M9P2S5V8X1Z4B",
                    "brand_id": "01JD2R1A3C5E7G9J1K3M5N7P9Q",
                    "status": "verified",
                    "subject": {
                      "id": "01JD2R2B4D6F8H0J2K4M6N8P0Q",
                      "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d",
                      "reference": "acct_4417",
                      "tier": 1
                    },
                    "request": {
                      "type": "wire",
                      "title": "Wire to Ridgeline Fabrication",
                      "summary": "The first payment on invoice 2291.",
                      "money": {
                        "amount_minor": 4500000,
                        "currency": "USD"
                      },
                      "counterparty": "Ridgeline Fabrication",
                      "reference": "INV-2291",
                      "requested_at": "2026-11-19T18:04:00.000Z"
                    },
                    "policy": {
                      "checks": [
                        "liveness",
                        "face_match"
                      ],
                      "allow_decline": true,
                      "allow_note": true,
                      "expires_in_seconds": 600
                    },
                    "callback": {
                      "url": "https://acme-bank.example/xipid/outcomes"
                    },
                    "metadata": {
                      "branch": "downtown"
                    },
                    "checks": [
                      {
                        "check": "liveness",
                        "passed": true,
                        "score": 0.98,
                        "mode": "movement_and_light",
                        "checked_at": "2026-11-19T18:06:41.090Z"
                      },
                      {
                        "check": "face_match",
                        "passed": true,
                        "score": 0.99,
                        "checked_at": "2026-11-19T18:06:41.090Z"
                      }
                    ],
                    "text": {
                      "status": "delivered"
                    },
                    "created_at": "2026-11-19T18:04:00.512Z",
                    "sent_at": "2026-11-19T18:04:01.204Z",
                    "expires_at": "2026-11-19T18:14:00.512Z",
                    "consent": {
                      "agreed_at": "2026-11-19T18:06:12.377Z",
                      "notice_version": "request-selfie-2026-11-02"
                    },
                    "opened_at": "2026-11-19T18:05:30.861Z",
                    "decided_at": "2026-11-19T18:06:41.090Z"
                  }
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_invalid`, `parameter_unknown`, `version_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential may not call this operation. Its code is one of `insufficient_scope`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "The credential does not allow this operation.",
                    "value": {
                      "error": {
                        "code": "insufficient_scope",
                        "message": "The credential does not allow this operation.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/insufficient_scope"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Nothing the credential may read goes by that id. Its code is one of `resource_not_found`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "No such resource.",
                    "value": {
                      "error": {
                        "code": "resource_not_found",
                        "message": "No such resource.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/resource_not_found"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/events/{id}/redeliver": {
      "post": {
        "operationId": "redeliverEvent",
        "tags": [
          "Events"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Deliver an event again",
        "description": "Delivers an event again, at once: its delivery starts over, pending, its attempts counted from none, on the schedule a first delivery follows.\n\n**Scope:** any live key of the brand.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** takes an `Idempotency-Key`, which it requires: a retry under the same key is answered what the first request was, for 24 hours, and the key sent with another request is refused.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "XipID's id for the event.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
            }
          },
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "The operation's key, 1 to 255 characters, best a UUID, in double quotes as a structured field string: a retry of the operation sends it again, and is answered what the first request was, for 24 hours.",
            "schema": {
              "type": "string",
              "maxLength": 512
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "responses": {
          "202": {
            "description": "The delivery as it now stands. `Location` names its challenge's deliveries, which show it as it goes.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delivery"
                },
                "example": {
                  "id": "01JD2RB7C9E1G3J5K7M9N1P3R5",
                  "challenge_id": "01JD2R5W8Y3K6M9P2S5V8X1Z4B",
                  "event": "challenge.verified",
                  "status": "pending",
                  "attempts": 0,
                  "next_attempt_at": "2026-11-20T09:15:02.448Z",
                  "created_at": "2026-11-19T18:06:41.090Z"
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_invalid`, `parameter_unknown`, `idempotency_key_missing`, `version_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "idempotency_key_missing": {
                    "summary": "This route requires an Idempotency-Key header.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_missing",
                        "message": "This route requires an Idempotency-Key header.",
                        "details": [
                          {
                            "path": "header.idempotency-key",
                            "code": "required",
                            "message": "Required."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_missing"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential may not call this operation. Its code is one of `insufficient_scope`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "The credential does not allow this operation.",
                    "value": {
                      "error": {
                        "code": "insufficient_scope",
                        "message": "The credential does not allow this operation.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/insufficient_scope"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Nothing the credential may read goes by that id. Its code is one of `resource_not_found`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "No such resource.",
                    "value": {
                      "error": {
                        "code": "resource_not_found",
                        "message": "No such resource.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/resource_not_found"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The resource's state refuses the request. Its code is one of `idempotency_key_in_use`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_in_use": {
                    "summary": "The first request with this Idempotency-Key is still running.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_in_use",
                        "message": "The first request with this Idempotency-Key is still running.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_in_use"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "A rule refuses the well-formed request. Its code is one of `idempotency_key_reused`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "summary": "This Idempotency-Key was used for a different request.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_reused",
                        "message": "This Idempotency-Key was used for a different request.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_reused"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/subjects": {
      "post": {
        "operationId": "createSubject",
        "tags": [
          "Subjects"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Refer a person",
        "description": "Refers a person by the brand's own reference for them, which travels in the body alone, with one channel, the name the brand knows them by, and the scopes it asks them to grant. XipID invites them by email, or the brand delivers the subject's `invite_url` on its own channel; the subject is pending until they accept, and then carries the pairwise identifier a challenge names them by. The same reference again repeats the referral and answers the same subject while it is live; asking other scopes of a person who accepted is refused.\n\n**Scope:** any live key of the brand.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** takes an `Idempotency-Key`, which it requires: a retry under the same key is answered what the first request was, for 24 hours, and the key sent with another request is refused.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "The operation's key, 1 to 255 characters, best a UUID, in double quotes as a structured field string: a retry of the operation sends it again, and is answered what the first request was, for 24 hours.",
            "schema": {
              "type": "string",
              "maxLength": 512
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateSubject"
              },
              "example": {
                "reference": "acct_4417",
                "display_name": "Sam Rivera",
                "channel": {
                  "type": "phone",
                  "to": "+16195550142"
                },
                "scopes": [
                  {
                    "attribute": "presence",
                    "purpose": "wire_approval"
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The live subject the reference already names, its referral repeated.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subject"
                },
                "example": {
                  "id": "01JD2R2B4D6F8H0J2K4M6N8P0Q",
                  "reference": "acct_4417",
                  "status": "pending",
                  "invite_url": "https://app.xipid.org/invitations",
                  "display_name": "Sam Rivera",
                  "channel": {
                    "type": "phone",
                    "to_masked": "+1 ••• ••• 0142"
                  },
                  "scopes": [
                    {
                      "attribute": "presence",
                      "purpose": "wire_approval"
                    }
                  ],
                  "created_at": "2026-11-18T15:20:07.311Z",
                  "updated_at": "2026-11-18T15:20:07.311Z"
                }
              }
            }
          },
          "201": {
            "description": "The subject the referral made. `Location` names it.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Location": {
                "$ref": "#/components/headers/Location"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subject"
                },
                "example": {
                  "id": "01JD2R2B4D6F8H0J2K4M6N8P0Q",
                  "reference": "acct_4417",
                  "status": "pending",
                  "invite_url": "https://app.xipid.org/invitations",
                  "display_name": "Sam Rivera",
                  "channel": {
                    "type": "phone",
                    "to_masked": "+1 ••• ••• 0142"
                  },
                  "scopes": [
                    {
                      "attribute": "presence",
                      "purpose": "wire_approval"
                    }
                  ],
                  "created_at": "2026-11-18T15:20:07.311Z",
                  "updated_at": "2026-11-18T15:20:07.311Z"
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_missing`, `parameter_invalid`, `parameter_unknown`, `idempotency_key_missing`, `version_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_missing": {
                    "summary": "The request lacks a required parameter.",
                    "value": {
                      "error": {
                        "code": "parameter_missing",
                        "message": "The request lacks a required parameter.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "required",
                            "message": "Required."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_missing"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "idempotency_key_missing": {
                    "summary": "This route requires an Idempotency-Key header.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_missing",
                        "message": "This route requires an Idempotency-Key header.",
                        "details": [
                          {
                            "path": "header.idempotency-key",
                            "code": "required",
                            "message": "Required."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_missing"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential may not call this operation. Its code is one of `insufficient_scope`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "The credential does not allow this operation.",
                    "value": {
                      "error": {
                        "code": "insufficient_scope",
                        "message": "The credential does not allow this operation.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/insufficient_scope"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The resource's state refuses the request. Its code is one of `idempotency_key_in_use`, `subject_scopes_accepted`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_in_use": {
                    "summary": "The first request with this Idempotency-Key is still running.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_in_use",
                        "message": "The first request with this Idempotency-Key is still running.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_in_use"
                      }
                    }
                  },
                  "subject_scopes_accepted": {
                    "summary": "The person accepted the scopes first asked, and asking for others needs their consent again.",
                    "value": {
                      "error": {
                        "code": "subject_scopes_accepted",
                        "message": "The person accepted the scopes first asked, and asking for others needs their consent again.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/subject_scopes_accepted"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "A rule refuses the well-formed request. Its code is one of `idempotency_key_reused`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "summary": "This Idempotency-Key was used for a different request.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_reused",
                        "message": "This Idempotency-Key was used for a different request.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_reused"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/subjects/search": {
      "post": {
        "operationId": "searchSubjects",
        "tags": [
          "Subjects"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Search subjects by reference",
        "description": "One page of the brand's subjects under one of its references, oldest first: the one it refers now and those the person unlinked before. The reference travels in the body, where no log keeps it.\n\n**Scope:** any live key of the brand.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** a read, safe to repeat.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SearchSubjects"
              },
              "example": {
                "reference": "acct_4417",
                "limit": 20
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "A page of subjects.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SubjectPage"
                },
                "example": {
                  "data": [
                    {
                      "id": "01JD2R2B4D6F8H0J2K4M6N8P0Q",
                      "reference": "acct_4417",
                      "status": "linked",
                      "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d",
                      "linked_at": "2026-11-18T15:42:55.020Z",
                      "display_name": "Sam Rivera",
                      "channel": {
                        "type": "phone",
                        "to_masked": "+1 ••• ••• 0142"
                      },
                      "scopes": [
                        {
                          "attribute": "presence",
                          "purpose": "wire_approval"
                        }
                      ],
                      "reference_face": {
                        "enrolled_at": "2026-11-18T16:01:13.668Z"
                      },
                      "created_at": "2026-11-18T15:20:07.311Z",
                      "updated_at": "2026-11-18T16:01:13.668Z"
                    }
                  ],
                  "has_more": false,
                  "next_cursor": null,
                  "previous_cursor": null
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_missing`, `parameter_invalid`, `parameter_unknown`, `version_invalid`, `cursor_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_missing": {
                    "summary": "The request lacks a required parameter.",
                    "value": {
                      "error": {
                        "code": "parameter_missing",
                        "message": "The request lacks a required parameter.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "required",
                            "message": "Required."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_missing"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  },
                  "cursor_invalid": {
                    "summary": "The cursor is malformed or belongs to another list.",
                    "value": {
                      "error": {
                        "code": "cursor_invalid",
                        "message": "The cursor is malformed or belongs to another list.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/cursor_invalid"
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential may not call this operation. Its code is one of `insufficient_scope`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "The credential does not allow this operation.",
                    "value": {
                      "error": {
                        "code": "insufficient_scope",
                        "message": "The credential does not allow this operation.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/insufficient_scope"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "A service XipID depends on failed. Its code is one of `upstream_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_error": {
                    "summary": "A service XipID depends on failed.",
                    "value": {
                      "error": {
                        "code": "upstream_error",
                        "message": "A service XipID depends on failed.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          },
          "504": {
            "description": "A service XipID depends on did not answer in time. Its code is one of `upstream_timeout`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_timeout": {
                    "summary": "A service XipID depends on did not answer in time.",
                    "value": {
                      "error": {
                        "code": "upstream_timeout",
                        "message": "A service XipID depends on did not answer in time.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_timeout"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/subjects/{id}": {
      "get": {
        "operationId": "getSubject",
        "tags": [
          "Subjects"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Read a subject",
        "description": "The subject as it stands, by XipID's id for it, with the pairwise identifier once the person linked. Its `ETag` may go back as `If-Match` with a change to its reference face. Each read is recorded as the brand's read, with the key that made it.\n\n**Scope:** any live key of the brand.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** a read, safe to repeat.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "XipID's id for the subject.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "responses": {
          "200": {
            "description": "The subject.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subject"
                },
                "example": {
                  "id": "01JD2R2B4D6F8H0J2K4M6N8P0Q",
                  "reference": "acct_4417",
                  "status": "linked",
                  "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d",
                  "linked_at": "2026-11-18T15:42:55.020Z",
                  "display_name": "Sam Rivera",
                  "channel": {
                    "type": "phone",
                    "to_masked": "+1 ••• ••• 0142"
                  },
                  "scopes": [
                    {
                      "attribute": "presence",
                      "purpose": "wire_approval"
                    }
                  ],
                  "reference_face": {
                    "enrolled_at": "2026-11-18T16:01:13.668Z"
                  },
                  "created_at": "2026-11-18T15:20:07.311Z",
                  "updated_at": "2026-11-18T16:01:13.668Z"
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_invalid`, `parameter_unknown`, `version_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential may not call this operation. Its code is one of `insufficient_scope`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "The credential does not allow this operation.",
                    "value": {
                      "error": {
                        "code": "insufficient_scope",
                        "message": "The credential does not allow this operation.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/insufficient_scope"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Nothing the credential may read goes by that id. Its code is one of `resource_not_found`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "No such resource.",
                    "value": {
                      "error": {
                        "code": "resource_not_found",
                        "message": "No such resource.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/resource_not_found"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/subjects/{id}/reference-face": {
      "put": {
        "operationId": "enrollReferenceFace",
        "tags": [
          "Subjects"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Enroll a reference face",
        "description": "Enrolls the face a selfie is matched to: one JPEG or PNG of at most 4 MB, in Base64, holding exactly one face, which replaces the face this brand enrolled before. Until the person accepts, it is held with the referral; once they have, it goes on file only where no face of their own is. XipID never sends it back: the subject shows when it was enrolled. With `If-Match`, it goes ahead only while the subject is as the brand last read it. The body may hold 6 MB, every other route's 1 MB.\n\n**Scope:** any live key of the brand.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** repeating it does what it did, and no more.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "XipID's id for the subject.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "description": "The `ETag` of the subject as the brand last read it, or a list of them: the change goes ahead only while the subject is as one says, and is refused `412` otherwise.",
            "schema": {
              "type": "string",
              "maxLength": 1024,
              "pattern": "^(?:\\*|(?:W\\/)?\"[\\x21\\x23-\\x7E]*\"(?:[ \\t]*,[ \\t]*(?:W\\/)?\"[\\x21\\x23-\\x7E]*\")*)$"
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EnrollReferenceFace"
              },
              "example": {
                "image": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAA=="
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The subject, read back once the face went on file.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "ETag": {
                "$ref": "#/components/headers/ETag"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Subject"
                },
                "example": {
                  "id": "01JD2R2B4D6F8H0J2K4M6N8P0Q",
                  "reference": "acct_4417",
                  "status": "linked",
                  "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d",
                  "linked_at": "2026-11-18T15:42:55.020Z",
                  "display_name": "Sam Rivera",
                  "channel": {
                    "type": "phone",
                    "to_masked": "+1 ••• ••• 0142"
                  },
                  "scopes": [
                    {
                      "attribute": "presence",
                      "purpose": "wire_approval"
                    }
                  ],
                  "reference_face": {
                    "enrolled_at": "2026-11-18T16:01:13.668Z"
                  },
                  "created_at": "2026-11-18T15:20:07.311Z",
                  "updated_at": "2026-11-18T16:01:13.668Z"
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_missing`, `parameter_invalid`, `parameter_unknown`, `version_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_missing": {
                    "summary": "The request lacks a required parameter.",
                    "value": {
                      "error": {
                        "code": "parameter_missing",
                        "message": "The request lacks a required parameter.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "required",
                            "message": "Required."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_missing"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential may not call this operation. Its code is one of `insufficient_scope`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "The credential does not allow this operation.",
                    "value": {
                      "error": {
                        "code": "insufficient_scope",
                        "message": "The credential does not allow this operation.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/insufficient_scope"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Nothing the credential may read goes by that id. Its code is one of `resource_not_found`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "No such resource.",
                    "value": {
                      "error": {
                        "code": "resource_not_found",
                        "message": "No such resource.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/resource_not_found"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The resource's state refuses the request. Its code is one of `resource_conflict`, `reference_face_on_file`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_conflict": {
                    "summary": "The resource's state conflicts with the request; read it again.",
                    "value": {
                      "error": {
                        "code": "resource_conflict",
                        "message": "The resource's state conflicts with the request; read it again.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/resource_conflict"
                      }
                    }
                  },
                  "reference_face_on_file": {
                    "summary": "The person has a face on file that this brand did not enroll, and it stays.",
                    "value": {
                      "error": {
                        "code": "reference_face_on_file",
                        "message": "The person has a face on file that this brand did not enroll, and it stays.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/reference_face_on_file"
                      }
                    }
                  }
                }
              }
            }
          },
          "412": {
            "description": "The subject is no longer as `If-Match` says. Its code is one of `precondition_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "precondition_failed": {
                    "summary": "If-Match does not match the resource's current ETag.",
                    "value": {
                      "error": {
                        "code": "precondition_failed",
                        "message": "If-Match does not match the resource's current ETag.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/precondition_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "A rule refuses the well-formed request. Its code is one of `reference_face_unusable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "reference_face_unusable": {
                    "summary": "The image cannot be a reference face.",
                    "value": {
                      "error": {
                        "code": "reference_face_unusable",
                        "message": "The image cannot be a reference face.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/reference_face_unusable",
                        "reason": "no_face"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "A service XipID depends on failed. Its code is one of `upstream_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_error": {
                    "summary": "A service XipID depends on failed.",
                    "value": {
                      "error": {
                        "code": "upstream_error",
                        "message": "A service XipID depends on failed.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          },
          "504": {
            "description": "A service XipID depends on did not answer in time. Its code is one of `upstream_timeout`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_timeout": {
                    "summary": "A service XipID depends on did not answer in time.",
                    "value": {
                      "error": {
                        "code": "upstream_timeout",
                        "message": "A service XipID depends on did not answer in time.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_timeout"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteReferenceFace",
        "tags": [
          "Subjects"
        ],
        "security": [
          {
            "apiKey": []
          }
        ],
        "summary": "Delete a reference face",
        "description": "Deletes the reference face this brand enrolled, from every store; deleting one that is gone is not an error. With `If-Match`, it goes ahead only while the subject is as the brand last read it.\n\n**Scope:** any live key of the brand.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** repeating it does what it did, and no more.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "XipID's id for the subject.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
            }
          },
          {
            "name": "If-Match",
            "in": "header",
            "required": false,
            "description": "The `ETag` of the subject as the brand last read it, or a list of them: the change goes ahead only while the subject is as one says, and is refused `412` otherwise.",
            "schema": {
              "type": "string",
              "maxLength": 1024,
              "pattern": "^(?:\\*|(?:W\\/)?\"[\\x21\\x23-\\x7E]*\"(?:[ \\t]*,[ \\t]*(?:W\\/)?\"[\\x21\\x23-\\x7E]*\")*)$"
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "responses": {
          "204": {
            "description": "Deleted, or gone already.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_invalid`, `parameter_unknown`, `version_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential may not call this operation. Its code is one of `insufficient_scope`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "The credential does not allow this operation.",
                    "value": {
                      "error": {
                        "code": "insufficient_scope",
                        "message": "The credential does not allow this operation.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/insufficient_scope"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Nothing the credential may read goes by that id. Its code is one of `resource_not_found`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "No such resource.",
                    "value": {
                      "error": {
                        "code": "resource_not_found",
                        "message": "No such resource.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/resource_not_found"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The resource's state refuses the request. Its code is one of `resource_conflict`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_conflict": {
                    "summary": "The resource's state conflicts with the request; read it again.",
                    "value": {
                      "error": {
                        "code": "resource_conflict",
                        "message": "The resource's state conflicts with the request; read it again.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/resource_conflict"
                      }
                    }
                  }
                }
              }
            }
          },
          "412": {
            "description": "The subject is no longer as `If-Match` says. Its code is one of `precondition_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "precondition_failed": {
                    "summary": "If-Match does not match the resource's current ETag.",
                    "value": {
                      "error": {
                        "code": "precondition_failed",
                        "message": "If-Match does not match the resource's current ETag.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/precondition_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "502": {
            "description": "A service XipID depends on failed. Its code is one of `upstream_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_error": {
                    "summary": "A service XipID depends on failed.",
                    "value": {
                      "error": {
                        "code": "upstream_error",
                        "message": "A service XipID depends on failed.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          },
          "504": {
            "description": "A service XipID depends on did not answer in time. Its code is one of `upstream_timeout`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "upstream_timeout": {
                    "summary": "A service XipID depends on did not answer in time.",
                    "value": {
                      "error": {
                        "code": "upstream_timeout",
                        "message": "A service XipID depends on did not answer in time.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/upstream_timeout"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/delegations": {
      "post": {
        "operationId": "createDelegation",
        "tags": [
          "Delegations"
        ],
        "security": [
          {
            "agentCredential": []
          }
        ],
        "summary": "Ask a person to delegate",
        "description": "Asks a person to delegate their presence to the agent, naming them by the pairwise identifier one of the agent's org's brands holds for them, with the purposes it is for and the instant the delegation would end, in the future and at most 90 days out. Nothing is sent to the person: the request waits on their XipID for 30 days, or until `ends_at` when that comes first, and they accept or decline it there. Asking the same person again replaces the open request. A pairwise identifier no brand of the agent's org holds is refused `subject_unlinked`, as one nobody holds. A retry under the same `Idempotency-Key` is answered the same request.\n\n**Scope:** any live credential of an agent.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** takes an `Idempotency-Key`, which it requires: a retry under the same key is answered what the first request was, for 24 hours, and the key sent with another request is refused.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "description": "The operation's key, 1 to 255 characters, best a UUID, in double quotes as a structured field string: a retry of the operation sends it again, and is answered what the first request was, for 24 hours.",
            "schema": {
              "type": "string",
              "maxLength": 512
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateDelegation"
              },
              "example": {
                "subject": {
                  "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d"
                },
                "scopes": [
                  {
                    "attribute": "presence",
                    "purpose": "wire_approval"
                  }
                ],
                "ends_at": "2027-01-31T00:00:00-05:00"
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "The request, waiting on the person. `Location` names it.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              },
              "Location": {
                "$ref": "#/components/headers/Location"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delegation"
                },
                "example": {
                  "id": "01JD2RE0F2H4K6M8N0P2Q4S6T8",
                  "status": "pending",
                  "subject": {
                    "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d"
                  },
                  "scopes": [
                    {
                      "attribute": "presence",
                      "purpose": "wire_approval"
                    }
                  ],
                  "ends_at": "2027-01-31T05:00:00.000Z",
                  "expires_at": "2026-12-18T15:30:12.408Z",
                  "created_at": "2026-11-18T15:30:12.408Z"
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_missing`, `parameter_invalid`, `parameter_unknown`, `idempotency_key_missing`, `version_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_missing": {
                    "summary": "The request lacks a required parameter.",
                    "value": {
                      "error": {
                        "code": "parameter_missing",
                        "message": "The request lacks a required parameter.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "required",
                            "message": "Required."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_missing"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "idempotency_key_missing": {
                    "summary": "This route requires an Idempotency-Key header.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_missing",
                        "message": "This route requires an Idempotency-Key header.",
                        "details": [
                          {
                            "path": "header.idempotency-key",
                            "code": "required",
                            "message": "Required."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_missing"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential may not call this operation. Its code is one of `insufficient_scope`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "The credential does not allow this operation.",
                    "value": {
                      "error": {
                        "code": "insufficient_scope",
                        "message": "The credential does not allow this operation.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/insufficient_scope"
                      }
                    }
                  }
                }
              }
            }
          },
          "409": {
            "description": "The resource's state refuses the request. Its code is one of `idempotency_key_in_use`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_in_use": {
                    "summary": "The first request with this Idempotency-Key is still running.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_in_use",
                        "message": "The first request with this Idempotency-Key is still running.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_in_use"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "422": {
            "description": "A rule refuses the well-formed request. Its code is one of `idempotency_key_reused`, `subject_unlinked`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "idempotency_key_reused": {
                    "summary": "This Idempotency-Key was used for a different request.",
                    "value": {
                      "error": {
                        "code": "idempotency_key_reused",
                        "message": "This Idempotency-Key was used for a different request.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/idempotency_key_reused"
                      }
                    }
                  },
                  "subject_unlinked": {
                    "summary": "The pairwise identifier names no person linked to this brand, or to a brand of this agent's org.",
                    "value": {
                      "error": {
                        "code": "subject_unlinked",
                        "message": "The pairwise identifier names no person linked to this brand, or to a brand of this agent's org.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/subject_unlinked",
                        "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/delegations/{id}": {
      "get": {
        "operationId": "getDelegation",
        "tags": [
          "Delegations"
        ],
        "security": [
          {
            "agentCredential": []
          }
        ],
        "summary": "Read a delegation request",
        "description": "The agent's request as it stands, and as it closed once it has: accepted, declined, expired, replaced by a newer request, or canceled when the agent was retired. An agent reads its own requests alone.\n\n**Scope:** any live credential of an agent.\n\n**Limits:** 1,000 requests a minute per key and 2,000 requests a minute per source address; every answer says what is left in `X-RateLimit-Remaining`, and a refusal when to come back in `Retry-After`.\n\n**Idempotency:** a read, safe to repeat.\n\n**Changes:** `2026-09-26`: added.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "XipID's id for the delegation request.",
            "schema": {
              "type": "string",
              "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
            }
          },
          {
            "$ref": "#/components/parameters/XipVersion"
          }
        ],
        "responses": {
          "200": {
            "description": "The request as it stands.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "X-RateLimit-Limit": {
                "$ref": "#/components/headers/X-RateLimit-Limit"
              },
              "X-RateLimit-Remaining": {
                "$ref": "#/components/headers/X-RateLimit-Remaining"
              },
              "X-RateLimit-Reset": {
                "$ref": "#/components/headers/X-RateLimit-Reset"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delegation"
                },
                "example": {
                  "id": "01JD2RE0F2H4K6M8N0P2Q4S6T8",
                  "status": "accepted",
                  "subject": {
                    "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d"
                  },
                  "scopes": [
                    {
                      "attribute": "presence",
                      "purpose": "wire_approval"
                    }
                  ],
                  "ends_at": "2027-01-31T05:00:00.000Z",
                  "expires_at": "2026-12-18T15:30:12.408Z",
                  "created_at": "2026-11-18T15:30:12.408Z",
                  "decided_at": "2026-11-18T15:47:31.902Z"
                }
              }
            }
          },
          "400": {
            "description": "The request is malformed. Its code is one of `json_invalid`, `parameter_invalid`, `parameter_unknown`, `version_invalid`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "json_invalid": {
                    "summary": "The request body is not valid JSON.",
                    "value": {
                      "error": {
                        "code": "json_invalid",
                        "message": "The request body is not valid JSON.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/json_invalid"
                      }
                    }
                  },
                  "parameter_invalid": {
                    "summary": "The request contains invalid parameters.",
                    "value": {
                      "error": {
                        "code": "parameter_invalid",
                        "message": "The request contains invalid parameters.",
                        "details": [
                          {
                            "path": "request.title",
                            "code": "too_big",
                            "message": "Too big: expected string to have <=120 characters."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_invalid"
                      }
                    }
                  },
                  "parameter_unknown": {
                    "summary": "The request contains a parameter this route does not take.",
                    "value": {
                      "error": {
                        "code": "parameter_unknown",
                        "message": "The request contains a parameter this route does not take.",
                        "details": [
                          {
                            "path": "request.color",
                            "code": "unknown",
                            "message": "This route does not take it."
                          }
                        ],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/parameter_unknown"
                      }
                    }
                  },
                  "version_invalid": {
                    "summary": "Xip-Version names no released version of this API.",
                    "value": {
                      "error": {
                        "code": "version_invalid",
                        "message": "Xip-Version names no released version of this API.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/version_invalid",
                        "valid_versions": [
                          "2026-09-26"
                        ]
                      }
                    }
                  }
                }
              }
            }
          },
          "401": {
            "description": "No key or credential, or not a live one. Its code is one of `authentication_required`, `authentication_failed`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "authentication_required": {
                    "summary": "Authentication is required.",
                    "value": {
                      "error": {
                        "code": "authentication_required",
                        "message": "Authentication is required.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_required"
                      }
                    }
                  },
                  "authentication_failed": {
                    "summary": "The credential is invalid, expired or revoked.",
                    "value": {
                      "error": {
                        "code": "authentication_failed",
                        "message": "The credential is invalid, expired or revoked.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/authentication_failed"
                      }
                    }
                  }
                }
              }
            }
          },
          "403": {
            "description": "The credential may not call this operation. Its code is one of `insufficient_scope`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "insufficient_scope": {
                    "summary": "The credential does not allow this operation.",
                    "value": {
                      "error": {
                        "code": "insufficient_scope",
                        "message": "The credential does not allow this operation.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/insufficient_scope"
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Nothing the credential may read goes by that id. Its code is one of `resource_not_found`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "resource_not_found": {
                    "summary": "No such resource.",
                    "value": {
                      "error": {
                        "code": "resource_not_found",
                        "message": "No such resource.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/resource_not_found"
                      }
                    }
                  }
                }
              }
            }
          },
          "413": {
            "description": "The body is over its limit. Its code is one of `content_too_large`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "content_too_large": {
                    "summary": "The request body is larger than this route accepts.",
                    "value": {
                      "error": {
                        "code": "content_too_large",
                        "message": "The request body is larger than this route accepts.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/content_too_large"
                      }
                    }
                  }
                }
              }
            }
          },
          "415": {
            "description": "The body is not JSON. Its code is one of `media_type_unsupported`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "media_type_unsupported": {
                    "summary": "This route does not accept that Content-Type.",
                    "value": {
                      "error": {
                        "code": "media_type_unsupported",
                        "message": "This route does not accept that Content-Type.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/media_type_unsupported"
                      }
                    }
                  }
                }
              }
            }
          },
          "429": {
            "description": "Too many requests, or a cap on what XipID sends; try again after `Retry-After`. Its code is one of `rate_limit_exceeded`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              },
              "Retry-After": {
                "$ref": "#/components/headers/Retry-After"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "rate_limit_exceeded": {
                    "summary": "Too many requests; try again later.",
                    "value": {
                      "error": {
                        "code": "rate_limit_exceeded",
                        "message": "Too many requests; try again later.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/rate_limit_exceeded"
                      }
                    }
                  }
                }
              }
            }
          },
          "500": {
            "description": "Something went wrong on our side. Its code is one of `internal_error`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "internal_error": {
                    "summary": "Something went wrong on our side.",
                    "value": {
                      "error": {
                        "code": "internal_error",
                        "message": "Something went wrong on our side.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/internal_error"
                      }
                    }
                  }
                }
              }
            }
          },
          "503": {
            "description": "The service is temporarily unavailable. Its code is one of `service_unavailable`.",
            "headers": {
              "X-Request-Id": {
                "$ref": "#/components/headers/X-Request-Id"
              },
              "Xip-Version": {
                "$ref": "#/components/headers/Xip-Version"
              }
            },
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                },
                "examples": {
                  "service_unavailable": {
                    "summary": "The service is temporarily unavailable.",
                    "value": {
                      "error": {
                        "code": "service_unavailable",
                        "message": "The service is temporarily unavailable.",
                        "details": [],
                        "request_id": "01JD2RD9E1G3J5K7M9N1P3R5S7",
                        "doc_url": "https://xipid.org/errors/service_unavailable"
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "webhooks": {
    "outcome": {
      "post": {
        "operationId": "receiveOutcome",
        "tags": [
          "Events"
        ],
        "summary": "Receive an outcome",
        "description": "When a challenge closes, XipID posts its event to the challenge's callback URL, signed per Standard Webhooks over the raw bytes: `webhook-id` is the event's id, the same on every attempt; `webhook-timestamp` the attempt's Unix time; `webhook-signature` one signature for each of the brand's active secrets.\n\nVerify a signature over the raw body before parsing it, refuse a timestamp more than 5 minutes from your clock, and process an event once by its id.\n\nA 2xx answer within 15 seconds delivers it. No answer, a 408, a 429 or a 5xx is tried again 5 seconds, 5 minutes, 30 minutes, 2 hours, 5 hours, 10 hours, 14 hours, 20 hours and 24 hours after each failed attempt, 10 attempts in all, each wait strayed by up to a fifth and lengthened to the receiver's `Retry-After`, up to 24 hours; a 3xx or another 4xx ends the delivery. A delivery that failed may be delivered again, and every event is listed at `GET /events` for 30 days.",
        "security": [],
        "parameters": [
          {
            "name": "webhook-id",
            "in": "header",
            "required": true,
            "description": "The event's id, the same on every attempt.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "webhook-timestamp",
            "in": "header",
            "required": true,
            "description": "The attempt's Unix time, in seconds.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "webhook-signature",
            "in": "header",
            "required": true,
            "description": "One signature for each of the brand's active secrets, separated by spaces: `v1,` and the Base64 of the HMAC-SHA256 of `{webhook-id}.{webhook-timestamp}.{body}` under the secret's key, as Standard Webhooks defines it.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Event"
              },
              "example": {
                "id": "01JD2RB7C9E1G3J5K7M9N1P3R5",
                "type": "challenge.verified",
                "api_version": "2026-09-26",
                "created_at": "2026-11-19T18:06:41.090Z",
                "data": {
                  "id": "01JD2R5W8Y3K6M9P2S5V8X1Z4B",
                  "brand_id": "01JD2R1A3C5E7G9J1K3M5N7P9Q",
                  "status": "verified",
                  "subject": {
                    "id": "01JD2R2B4D6F8H0J2K4M6N8P0Q",
                    "pairwise_id": "Vb3kQ9xR2mTz7LpW4nYc8d",
                    "reference": "acct_4417",
                    "tier": 1
                  },
                  "request": {
                    "type": "wire",
                    "title": "Wire to Ridgeline Fabrication",
                    "summary": "The first payment on invoice 2291.",
                    "money": {
                      "amount_minor": 4500000,
                      "currency": "USD"
                    },
                    "counterparty": "Ridgeline Fabrication",
                    "reference": "INV-2291",
                    "requested_at": "2026-11-19T18:04:00.000Z"
                  },
                  "policy": {
                    "checks": [
                      "liveness",
                      "face_match"
                    ],
                    "allow_decline": true,
                    "allow_note": true,
                    "expires_in_seconds": 600
                  },
                  "callback": {
                    "url": "https://acme-bank.example/xipid/outcomes"
                  },
                  "metadata": {
                    "branch": "downtown"
                  },
                  "checks": [
                    {
                      "check": "liveness",
                      "passed": true,
                      "score": 0.98,
                      "mode": "movement_and_light",
                      "checked_at": "2026-11-19T18:06:41.090Z"
                    },
                    {
                      "check": "face_match",
                      "passed": true,
                      "score": 0.99,
                      "checked_at": "2026-11-19T18:06:41.090Z"
                    }
                  ],
                  "text": {
                    "status": "delivered"
                  },
                  "created_at": "2026-11-19T18:04:00.512Z",
                  "sent_at": "2026-11-19T18:04:01.204Z",
                  "expires_at": "2026-11-19T18:14:00.512Z",
                  "consent": {
                    "agreed_at": "2026-11-19T18:06:12.377Z",
                    "notice_version": "request-selfie-2026-11-02"
                  },
                  "opened_at": "2026-11-19T18:05:30.861Z",
                  "decided_at": "2026-11-19T18:06:41.090Z"
                }
              }
            }
          }
        },
        "responses": {
          "2XX": {
            "description": "Received: the delivery is done."
          },
          "4XX": {
            "description": "Refused: a 408 or a 429 is tried again, any other ends the delivery."
          },
          "5XX": {
            "description": "Failed: tried again on the schedule."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Challenge": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "brand_id": {
            "type": "string",
            "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "created",
              "sent",
              "opened",
              "approving",
              "verified",
              "check_failed",
              "declined",
              "expired",
              "canceled"
            ],
            "description": "Where the challenge is in its life; the last five are final.",
            "x-enumDescriptions": {
              "created": "Made; the text with its link is not sent yet.",
              "sent": "The text with the link went to the person's phone.",
              "opened": "The person opened the link and is reading the request.",
              "approving": "The person approved, and the checks the policy asks for are running.",
              "verified": "The person approved and every check passed. Final.",
              "check_failed": "A check the policy asks for did not pass. Final.",
              "declined": "The person declined. Final.",
              "expired": "No decision came before `expires_at`. Final.",
              "canceled": "The brand canceled it, or its text could not be sent. Final."
            }
          },
          "subject": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
              },
              "pairwise_id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{22}$"
              },
              "reference": {
                "type": "string"
              },
              "tier": {
                "type": "number",
                "enum": [
                  0,
                  1,
                  2
                ],
                "description": "How far the person's identity is verified.",
                "x-enumDescriptions": {
                  "0": "Their phone and email are verified.",
                  "1": "A selfie too, which keeps their reference face.",
                  "2": "A government document too."
                }
              }
            },
            "required": [
              "id",
              "pairwise_id",
              "reference"
            ]
          },
          "request": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "wire",
                  "beneficiary_change",
                  "withdrawal",
                  "password_reset",
                  "address_change",
                  "other"
                ],
                "description": "What the brand asks the person to approve.",
                "x-enumDescriptions": {
                  "wire": "A wire transfer.",
                  "beneficiary_change": "A change to whom a payment goes.",
                  "withdrawal": "A withdrawal of funds.",
                  "password_reset": "A reset of a password.",
                  "address_change": "A change of address.",
                  "other": "Anything else; the title says what."
                }
              },
              "title": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "summary": {
                "type": "string",
                "maxLength": 280
              },
              "money": {
                "type": "object",
                "properties": {
                  "amount_minor": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "currency": {
                    "type": "string",
                    "pattern": "^[A-Z]{3}$"
                  }
                },
                "required": [
                  "amount_minor",
                  "currency"
                ]
              },
              "counterparty": {
                "type": "string",
                "maxLength": 200
              },
              "reference": {
                "type": "string",
                "maxLength": 120
              },
              "requested_at": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
              }
            },
            "required": [
              "type",
              "title",
              "requested_at"
            ]
          },
          "policy": {
            "type": "object",
            "properties": {
              "checks": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "liveness",
                    "face_match"
                  ],
                  "description": "A check the page runs before an approval counts.",
                  "x-enumDescriptions": {
                    "liveness": "The selfie is of a live person at the phone, not a photo or a recording.",
                    "face_match": "The selfie's face matches the person's reference face."
                  }
                }
              },
              "allow_decline": {
                "type": "boolean"
              },
              "allow_note": {
                "type": "boolean"
              },
              "expires_in_seconds": {
                "type": "integer",
                "minimum": 60,
                "maximum": 3600
              }
            },
            "required": [
              "checks",
              "allow_decline",
              "allow_note",
              "expires_in_seconds"
            ]
          },
          "callback": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string",
                "maxLength": 2048,
                "format": "uri"
              }
            },
            "required": [
              "url"
            ]
          },
          "metadata": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "type": "string"
            }
          },
          "agent": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
              },
              "key": {
                "type": "string",
                "pattern": "^[a-z0-9](?:[a-z0-9-]{0,38}[a-z0-9])?$"
              },
              "version": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              },
              "name": {
                "type": "string"
              },
              "org": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ]
              },
              "credential_id": {
                "type": "string",
                "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
              }
            },
            "required": [
              "id",
              "key",
              "version",
              "name",
              "org",
              "credential_id"
            ]
          },
          "checks": {
            "type": "array",
            "items": {
              "oneOf": [
                {
                  "type": "object",
                  "properties": {
                    "check": {
                      "type": "string",
                      "enum": [
                        "liveness",
                        "face_match"
                      ],
                      "description": "A check the page runs before an approval counts.",
                      "x-enumDescriptions": {
                        "liveness": "The selfie is of a live person at the phone, not a photo or a recording.",
                        "face_match": "The selfie's face matches the person's reference face."
                      }
                    },
                    "passed": {
                      "type": "boolean",
                      "const": true
                    },
                    "score": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "movement_and_light",
                        "movement"
                      ],
                      "description": "The liveness mode the vendor says ran.",
                      "x-enumDescriptions": {
                        "movement_and_light": "Colored lights flashed on the screen during the selfie.",
                        "movement": "No lights, for a device that asks for reduced motion; the vendor rates it the less accurate."
                      }
                    },
                    "checked_at": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
                    }
                  },
                  "required": [
                    "check",
                    "passed",
                    "checked_at"
                  ]
                },
                {
                  "type": "object",
                  "properties": {
                    "check": {
                      "type": "string",
                      "enum": [
                        "liveness",
                        "face_match"
                      ],
                      "description": "A check the page runs before an approval counts.",
                      "x-enumDescriptions": {
                        "liveness": "The selfie is of a live person at the phone, not a photo or a recording.",
                        "face_match": "The selfie's face matches the person's reference face."
                      }
                    },
                    "passed": {
                      "type": "boolean",
                      "const": false
                    },
                    "score": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "movement_and_light",
                        "movement"
                      ],
                      "description": "The liveness mode the vendor says ran.",
                      "x-enumDescriptions": {
                        "movement_and_light": "Colored lights flashed on the screen during the selfie.",
                        "movement": "No lights, for a device that asks for reduced motion; the vendor rates it the less accurate."
                      }
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "below_threshold",
                        "no_face",
                        "capture_failed",
                        "reference_missing"
                      ],
                      "description": "Why the check did not pass.",
                      "x-enumDescriptions": {
                        "below_threshold": "It scored under the threshold XipID holds it to.",
                        "no_face": "The vendor found no face to score.",
                        "capture_failed": "The selfie did not complete.",
                        "reference_missing": "The brand deleted the reference face while the challenge was open."
                      }
                    },
                    "checked_at": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
                    }
                  },
                  "required": [
                    "check",
                    "passed",
                    "reason",
                    "checked_at"
                  ]
                }
              ]
            }
          },
          "consent": {
            "type": "object",
            "properties": {
              "agreed_at": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
              },
              "notice_version": {
                "type": "string",
                "enum": [
                  "request-selfie-2026-11-02",
                  "person-selfie-2026-11-02",
                  "request-selfie-frames-2026-11-02"
                ],
                "description": "The notice the person agreed to before the selfie, by its version.",
                "x-enumDescriptions": {
                  "request-selfie-2026-11-02": "A request's selfie notice of November 2, 2026, for a brand that keeps no frames.",
                  "person-selfie-2026-11-02": "The notice of November 2, 2026, before the selfie that takes a person to Tier 1.",
                  "request-selfie-frames-2026-11-02": "A request's selfie notice of November 2, 2026, for a brand that keeps frames, which says so and that the brand may get them only if the request is disputed."
                }
              }
            },
            "required": [
              "agreed_at",
              "notice_version"
            ]
          },
          "note": {
            "type": "string"
          },
          "text": {
            "type": "object",
            "properties": {
              "provider_message_id": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "accepted",
                  "queued",
                  "sending",
                  "sent",
                  "delivered",
                  "undelivered",
                  "failed"
                ],
                "description": "What became of the text, as the channel reports it; the last three are final.",
                "x-enumDescriptions": {
                  "accepted": "The provider took the text.",
                  "queued": "The provider holds the text before the carrier has it.",
                  "sending": "The text is on its way to the carrier.",
                  "sent": "The carrier has the text.",
                  "delivered": "The phone received the text. Final.",
                  "undelivered": "The carrier could not deliver the text. Final.",
                  "failed": "The provider could not send the text. Final."
                }
              },
              "error_code": {
                "type": "string"
              }
            },
            "required": [
              "status"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "sent_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "opened_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "decided_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          }
        },
        "required": [
          "id",
          "brand_id",
          "status",
          "subject",
          "request",
          "policy",
          "callback",
          "checks",
          "created_at",
          "expires_at"
        ]
      },
      "ChallengeCreated": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "brand_id": {
            "type": "string",
            "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "created",
              "sent",
              "opened",
              "approving",
              "verified",
              "check_failed",
              "declined",
              "expired",
              "canceled"
            ],
            "description": "Where the challenge is in its life; the last five are final.",
            "x-enumDescriptions": {
              "created": "Made; the text with its link is not sent yet.",
              "sent": "The text with the link went to the person's phone.",
              "opened": "The person opened the link and is reading the request.",
              "approving": "The person approved, and the checks the policy asks for are running.",
              "verified": "The person approved and every check passed. Final.",
              "check_failed": "A check the policy asks for did not pass. Final.",
              "declined": "The person declined. Final.",
              "expired": "No decision came before `expires_at`. Final.",
              "canceled": "The brand canceled it, or its text could not be sent. Final."
            }
          },
          "subject": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
              },
              "pairwise_id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{22}$"
              },
              "reference": {
                "type": "string"
              },
              "tier": {
                "type": "number",
                "enum": [
                  0,
                  1,
                  2
                ],
                "description": "How far the person's identity is verified.",
                "x-enumDescriptions": {
                  "0": "Their phone and email are verified.",
                  "1": "A selfie too, which keeps their reference face.",
                  "2": "A government document too."
                }
              }
            },
            "required": [
              "id",
              "pairwise_id",
              "reference"
            ]
          },
          "request": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "wire",
                  "beneficiary_change",
                  "withdrawal",
                  "password_reset",
                  "address_change",
                  "other"
                ],
                "description": "What the brand asks the person to approve.",
                "x-enumDescriptions": {
                  "wire": "A wire transfer.",
                  "beneficiary_change": "A change to whom a payment goes.",
                  "withdrawal": "A withdrawal of funds.",
                  "password_reset": "A reset of a password.",
                  "address_change": "A change of address.",
                  "other": "Anything else; the title says what."
                }
              },
              "title": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "summary": {
                "type": "string",
                "maxLength": 280
              },
              "money": {
                "type": "object",
                "properties": {
                  "amount_minor": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "currency": {
                    "type": "string",
                    "pattern": "^[A-Z]{3}$"
                  }
                },
                "required": [
                  "amount_minor",
                  "currency"
                ]
              },
              "counterparty": {
                "type": "string",
                "maxLength": 200
              },
              "reference": {
                "type": "string",
                "maxLength": 120
              },
              "requested_at": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
              }
            },
            "required": [
              "type",
              "title",
              "requested_at"
            ]
          },
          "policy": {
            "type": "object",
            "properties": {
              "checks": {
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "liveness",
                    "face_match"
                  ],
                  "description": "A check the page runs before an approval counts.",
                  "x-enumDescriptions": {
                    "liveness": "The selfie is of a live person at the phone, not a photo or a recording.",
                    "face_match": "The selfie's face matches the person's reference face."
                  }
                }
              },
              "allow_decline": {
                "type": "boolean"
              },
              "allow_note": {
                "type": "boolean"
              },
              "expires_in_seconds": {
                "type": "integer",
                "minimum": 60,
                "maximum": 3600
              }
            },
            "required": [
              "checks",
              "allow_decline",
              "allow_note",
              "expires_in_seconds"
            ]
          },
          "callback": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string",
                "maxLength": 2048,
                "format": "uri"
              }
            },
            "required": [
              "url"
            ]
          },
          "metadata": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {
              "type": "string"
            }
          },
          "agent": {
            "type": "object",
            "properties": {
              "id": {
                "type": "string",
                "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
              },
              "key": {
                "type": "string",
                "pattern": "^[a-z0-9](?:[a-z0-9-]{0,38}[a-z0-9])?$"
              },
              "version": {
                "type": "integer",
                "exclusiveMinimum": 0,
                "maximum": 9007199254740991
              },
              "name": {
                "type": "string"
              },
              "org": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string"
                  }
                },
                "required": [
                  "name"
                ]
              },
              "credential_id": {
                "type": "string",
                "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
              }
            },
            "required": [
              "id",
              "key",
              "version",
              "name",
              "org",
              "credential_id"
            ]
          },
          "checks": {
            "type": "array",
            "items": {
              "oneOf": [
                {
                  "type": "object",
                  "properties": {
                    "check": {
                      "type": "string",
                      "enum": [
                        "liveness",
                        "face_match"
                      ],
                      "description": "A check the page runs before an approval counts.",
                      "x-enumDescriptions": {
                        "liveness": "The selfie is of a live person at the phone, not a photo or a recording.",
                        "face_match": "The selfie's face matches the person's reference face."
                      }
                    },
                    "passed": {
                      "type": "boolean",
                      "const": true
                    },
                    "score": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "movement_and_light",
                        "movement"
                      ],
                      "description": "The liveness mode the vendor says ran.",
                      "x-enumDescriptions": {
                        "movement_and_light": "Colored lights flashed on the screen during the selfie.",
                        "movement": "No lights, for a device that asks for reduced motion; the vendor rates it the less accurate."
                      }
                    },
                    "checked_at": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
                    }
                  },
                  "required": [
                    "check",
                    "passed",
                    "checked_at"
                  ]
                },
                {
                  "type": "object",
                  "properties": {
                    "check": {
                      "type": "string",
                      "enum": [
                        "liveness",
                        "face_match"
                      ],
                      "description": "A check the page runs before an approval counts.",
                      "x-enumDescriptions": {
                        "liveness": "The selfie is of a live person at the phone, not a photo or a recording.",
                        "face_match": "The selfie's face matches the person's reference face."
                      }
                    },
                    "passed": {
                      "type": "boolean",
                      "const": false
                    },
                    "score": {
                      "type": "number",
                      "minimum": 0,
                      "maximum": 1
                    },
                    "mode": {
                      "type": "string",
                      "enum": [
                        "movement_and_light",
                        "movement"
                      ],
                      "description": "The liveness mode the vendor says ran.",
                      "x-enumDescriptions": {
                        "movement_and_light": "Colored lights flashed on the screen during the selfie.",
                        "movement": "No lights, for a device that asks for reduced motion; the vendor rates it the less accurate."
                      }
                    },
                    "reason": {
                      "type": "string",
                      "enum": [
                        "below_threshold",
                        "no_face",
                        "capture_failed",
                        "reference_missing"
                      ],
                      "description": "Why the check did not pass.",
                      "x-enumDescriptions": {
                        "below_threshold": "It scored under the threshold XipID holds it to.",
                        "no_face": "The vendor found no face to score.",
                        "capture_failed": "The selfie did not complete.",
                        "reference_missing": "The brand deleted the reference face while the challenge was open."
                      }
                    },
                    "checked_at": {
                      "type": "string",
                      "format": "date-time",
                      "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
                    }
                  },
                  "required": [
                    "check",
                    "passed",
                    "reason",
                    "checked_at"
                  ]
                }
              ]
            }
          },
          "consent": {
            "type": "object",
            "properties": {
              "agreed_at": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
              },
              "notice_version": {
                "type": "string",
                "enum": [
                  "request-selfie-2026-11-02",
                  "person-selfie-2026-11-02",
                  "request-selfie-frames-2026-11-02"
                ],
                "description": "The notice the person agreed to before the selfie, by its version.",
                "x-enumDescriptions": {
                  "request-selfie-2026-11-02": "A request's selfie notice of November 2, 2026, for a brand that keeps no frames.",
                  "person-selfie-2026-11-02": "The notice of November 2, 2026, before the selfie that takes a person to Tier 1.",
                  "request-selfie-frames-2026-11-02": "A request's selfie notice of November 2, 2026, for a brand that keeps frames, which says so and that the brand may get them only if the request is disputed."
                }
              }
            },
            "required": [
              "agreed_at",
              "notice_version"
            ]
          },
          "note": {
            "type": "string"
          },
          "text": {
            "type": "object",
            "properties": {
              "provider_message_id": {
                "type": "string"
              },
              "status": {
                "type": "string",
                "enum": [
                  "accepted",
                  "queued",
                  "sending",
                  "sent",
                  "delivered",
                  "undelivered",
                  "failed"
                ],
                "description": "What became of the text, as the channel reports it; the last three are final.",
                "x-enumDescriptions": {
                  "accepted": "The provider took the text.",
                  "queued": "The provider holds the text before the carrier has it.",
                  "sending": "The text is on its way to the carrier.",
                  "sent": "The carrier has the text.",
                  "delivered": "The phone received the text. Final.",
                  "undelivered": "The carrier could not deliver the text. Final.",
                  "failed": "The provider could not send the text. Final."
                }
              },
              "error_code": {
                "type": "string"
              }
            },
            "required": [
              "status"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "sent_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "opened_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "decided_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "link": {
            "anyOf": [
              {
                "type": "string",
                "maxLength": 2048,
                "format": "uri"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "id",
          "brand_id",
          "status",
          "subject",
          "request",
          "policy",
          "callback",
          "checks",
          "created_at",
          "expires_at",
          "link"
        ]
      },
      "CaptureFrames": {
        "type": "object",
        "properties": {
          "challenge_id": {
            "type": "string",
            "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "frames": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "capture_id": {
                  "type": "string",
                  "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
                },
                "position": {
                  "type": "integer",
                  "minimum": 0,
                  "maximum": 3
                },
                "content_type": {
                  "type": "string",
                  "enum": [
                    "image/jpeg",
                    "image/png"
                  ],
                  "description": "The image's format, read from its bytes.",
                  "x-enumDescriptions": {
                    "image/jpeg": "A JPEG image.",
                    "image/png": "A PNG image."
                  }
                },
                "image": {
                  "type": "string",
                  "minLength": 1,
                  "format": "base64",
                  "contentEncoding": "base64",
                  "pattern": "^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$"
                },
                "captured_at": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
                },
                "expires_at": {
                  "type": "string",
                  "format": "date-time",
                  "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
                }
              },
              "required": [
                "capture_id",
                "position",
                "content_type",
                "image",
                "captured_at",
                "expires_at"
              ]
            }
          }
        },
        "required": [
          "challenge_id",
          "frames"
        ]
      },
      "Delivery": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "challenge_id": {
            "type": "string",
            "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "event": {
            "type": "string",
            "enum": [
              "challenge.verified",
              "challenge.check_failed",
              "challenge.declined",
              "challenge.expired",
              "challenge.canceled"
            ],
            "description": "How the challenge closed.",
            "x-enumDescriptions": {
              "challenge.verified": "The person approved and every check passed.",
              "challenge.check_failed": "A check the policy asks for did not pass.",
              "challenge.declined": "The person declined.",
              "challenge.expired": "No decision came before the challenge expired.",
              "challenge.canceled": "The brand canceled the challenge, or its text could not be sent."
            }
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "delivered",
              "failed"
            ],
            "description": "Where the delivery stands.",
            "x-enumDescriptions": {
              "pending": "An attempt is due or running.",
              "delivered": "The receiver answered 2xx.",
              "failed": "Its attempts are spent, or the receiver answered a status that ends them."
            }
          },
          "attempts": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "last_attempt": {
            "type": "object",
            "properties": {
              "attempted_at": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
              },
              "duration_ms": {
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "status_code": {
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "response_headers": {
                "type": "object",
                "propertyNames": {
                  "type": "string"
                },
                "additionalProperties": {
                  "type": "string"
                }
              },
              "response_body": {
                "type": "string"
              },
              "failure": {
                "type": "string",
                "enum": [
                  "timeout",
                  "dns_failure",
                  "connection_refused",
                  "connection_reset",
                  "tls_error",
                  "url_refused"
                ],
                "description": "Why the attempt got no answer, by its class alone.",
                "x-enumDescriptions": {
                  "timeout": "The attempt ran out of its 15 seconds.",
                  "dns_failure": "The callback URL's host did not resolve.",
                  "connection_refused": "The receiver refused the connection.",
                  "connection_reset": "The receiver reset the connection.",
                  "tls_error": "TLS failed.",
                  "url_refused": "The callback URL was refused before anything was sent: not https on port 443, or not public."
                }
              }
            },
            "required": [
              "attempted_at",
              "duration_ms"
            ]
          },
          "next_attempt_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "delivered_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          }
        },
        "required": [
          "id",
          "challenge_id",
          "event",
          "status",
          "attempts",
          "created_at"
        ]
      },
      "DeliveryPage": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Delivery"
            }
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,512}$"
              },
              {
                "type": "null"
              }
            ]
          },
          "previous_cursor": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,512}$"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "data",
          "has_more",
          "next_cursor",
          "previous_cursor"
        ]
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "type": {
            "type": "string",
            "enum": [
              "challenge.verified",
              "challenge.check_failed",
              "challenge.declined",
              "challenge.expired",
              "challenge.canceled"
            ],
            "description": "How the challenge closed.",
            "x-enumDescriptions": {
              "challenge.verified": "The person approved and every check passed.",
              "challenge.check_failed": "A check the policy asks for did not pass.",
              "challenge.declined": "The person declined.",
              "challenge.expired": "No decision came before the challenge expired.",
              "challenge.canceled": "The brand canceled the challenge, or its text could not be sent."
            }
          },
          "api_version": {
            "type": "string",
            "enum": [
              "2026-09-26"
            ],
            "description": "A released version of the API, named by the day its contract was fixed.",
            "x-enumDescriptions": {
              "2026-09-26": "The first version: challenges, subjects and events, and the signed outcome."
            }
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "data": {
            "$ref": "#/components/schemas/Challenge"
          }
        },
        "required": [
          "id",
          "type",
          "api_version",
          "created_at",
          "data"
        ]
      },
      "EventPage": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Event"
            }
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,512}$"
              },
              {
                "type": "null"
              }
            ]
          },
          "previous_cursor": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,512}$"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "data",
          "has_more",
          "next_cursor",
          "previous_cursor"
        ]
      },
      "Subject": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "reference": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "linked",
              "declined",
              "expired",
              "unlinked"
            ],
            "description": "Where the referral stands for the brand; the last three are final.",
            "x-enumDescriptions": {
              "pending": "Waiting on the person to accept.",
              "linked": "The person accepted: the brand has their pairwise identifier and may challenge them.",
              "declined": "The person declined. Final.",
              "expired": "Unanswered for thirty days. Final.",
              "unlinked": "The person took the brand's access back. Final."
            }
          },
          "pairwise_id": {
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{22}$"
          },
          "linked_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "invite_url": {
            "type": "string",
            "maxLength": 2048,
            "format": "uri"
          },
          "display_name": {
            "type": "string"
          },
          "channel": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "phone",
                  "email"
                ],
                "description": "The channel the brand referred the person by.",
                "x-enumDescriptions": {
                  "phone": "A phone number.",
                  "email": "An email address."
                }
              },
              "to_masked": {
                "type": "string"
              }
            },
            "required": [
              "type"
            ]
          },
          "scopes": {
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "attribute": {
                  "type": "string",
                  "enum": [
                    "presence",
                    "name",
                    "date_of_birth",
                    "email",
                    "phone",
                    "address",
                    "tier",
                    "ssn_match"
                  ],
                  "description": "What the scope lets the brand do with the person.",
                  "x-enumDescriptions": {
                    "presence": "Ask them to confirm it is really them, by a challenge.",
                    "name": "See their name.",
                    "date_of_birth": "See their date of birth.",
                    "email": "See their email address.",
                    "phone": "See their phone number.",
                    "address": "See their address.",
                    "tier": "See their verification tier.",
                    "ssn_match": "Check that a Social Security number the brand holds is theirs."
                  }
                },
                "purpose": {
                  "type": "string",
                  "pattern": "^[a-z][a-z0-9_]{2,39}$"
                }
              },
              "required": [
                "attribute",
                "purpose"
              ]
            }
          },
          "reference_face": {
            "type": "object",
            "properties": {
              "enrolled_at": {
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
              }
            },
            "required": [
              "enrolled_at"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "updated_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          }
        },
        "required": [
          "id",
          "reference",
          "status",
          "channel",
          "scopes",
          "created_at",
          "updated_at"
        ]
      },
      "SubjectPage": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Subject"
            }
          },
          "has_more": {
            "type": "boolean"
          },
          "next_cursor": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,512}$"
              },
              {
                "type": "null"
              }
            ]
          },
          "previous_cursor": {
            "anyOf": [
              {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{1,512}$"
              },
              {
                "type": "null"
              }
            ]
          }
        },
        "required": [
          "data",
          "has_more",
          "next_cursor",
          "previous_cursor"
        ]
      },
      "Delegation": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "accepted",
              "declined",
              "expired",
              "replaced",
              "canceled"
            ],
            "description": "Where the request is: waiting on the person, or how it closed; every value but the first is final.",
            "x-enumDescriptions": {
              "pending": "Waiting on the person, who sees it on their XipID.",
              "accepted": "The person accepted: the delegation holds until `ends_at`, unless they revoke it first.",
              "declined": "The person declined, and nothing was granted.",
              "expired": "No answer came by `expires_at`: 30 days after the request, or `ends_at` when that came first.",
              "replaced": "The agent asked the person again, and the newer request took its place.",
              "canceled": "The agent was retired."
            }
          },
          "subject": {
            "type": "object",
            "properties": {
              "pairwise_id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{22}$"
              }
            },
            "required": [
              "pairwise_id"
            ]
          },
          "scopes": {
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "attribute": {
                  "type": "string",
                  "enum": [
                    "presence",
                    "name",
                    "date_of_birth",
                    "email",
                    "phone",
                    "address",
                    "tier",
                    "ssn_match"
                  ],
                  "description": "What the scope lets the brand do with the person.",
                  "x-enumDescriptions": {
                    "presence": "Ask them to confirm it is really them, by a challenge.",
                    "name": "See their name.",
                    "date_of_birth": "See their date of birth.",
                    "email": "See their email address.",
                    "phone": "See their phone number.",
                    "address": "See their address.",
                    "tier": "See their verification tier.",
                    "ssn_match": "Check that a Social Security number the brand holds is theirs."
                  }
                },
                "purpose": {
                  "type": "string",
                  "pattern": "^[a-z][a-z0-9_]{2,39}$"
                }
              },
              "required": [
                "attribute",
                "purpose"
              ]
            }
          },
          "ends_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "expires_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          },
          "decided_at": {
            "type": "string",
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
          }
        },
        "required": [
          "id",
          "status",
          "subject",
          "scopes",
          "ends_at",
          "expires_at",
          "created_at"
        ]
      },
      "Error": {
        "type": "object",
        "properties": {
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "json_invalid",
                  "parameter_missing",
                  "parameter_invalid",
                  "parameter_unknown",
                  "idempotency_key_missing",
                  "version_invalid",
                  "cursor_invalid",
                  "authentication_required",
                  "authentication_failed",
                  "insufficient_scope",
                  "resource_not_found",
                  "method_not_allowed",
                  "resource_conflict",
                  "idempotency_key_in_use",
                  "endpoint_removed",
                  "precondition_failed",
                  "content_too_large",
                  "media_type_unsupported",
                  "idempotency_key_reused",
                  "precondition_required",
                  "rate_limit_exceeded",
                  "internal_error",
                  "upstream_error",
                  "service_unavailable",
                  "upstream_timeout",
                  "challenge_closed",
                  "invitation_changed",
                  "delegation_changed",
                  "agent_version_taken",
                  "subject_scopes_accepted",
                  "brand_slug_taken",
                  "email_reserved",
                  "reference_face_on_file",
                  "subject_unlinked",
                  "consent_missing",
                  "channel_unavailable",
                  "reference_face_missing",
                  "reference_face_unusable",
                  "callback_url_refused",
                  "text_failed",
                  "email_failed",
                  "code_invalid",
                  "code_expired",
                  "code_used",
                  "code_resend_too_soon",
                  "registration_expired",
                  "test_identity_refused",
                  "link_expired",
                  "link_used",
                  "decline_not_allowed",
                  "selfie_limit_reached",
                  "document_limit_reached",
                  "owner_required",
                  "member_exists",
                  "member_invitation_closed",
                  "member_invitation_other_address"
                ],
                "description": "What went wrong, for a client to branch on; each code's page is at `doc_url`.",
                "x-enumDescriptions": {
                  "json_invalid": "The request body is not valid JSON.",
                  "parameter_missing": "The request lacks a required parameter.",
                  "parameter_invalid": "The request contains invalid parameters.",
                  "parameter_unknown": "The request contains a parameter this route does not take.",
                  "idempotency_key_missing": "This route requires an Idempotency-Key header.",
                  "version_invalid": "Xip-Version names no released version of this API.",
                  "cursor_invalid": "The cursor is malformed or belongs to another list.",
                  "authentication_required": "Authentication is required.",
                  "authentication_failed": "The credential is invalid, expired or revoked.",
                  "insufficient_scope": "The credential does not allow this operation.",
                  "resource_not_found": "No such resource.",
                  "method_not_allowed": "This path does not take that method.",
                  "resource_conflict": "The resource's state conflicts with the request; read it again.",
                  "idempotency_key_in_use": "The first request with this Idempotency-Key is still running.",
                  "endpoint_removed": "This endpoint was removed at its sunset.",
                  "precondition_failed": "If-Match does not match the resource's current ETag.",
                  "content_too_large": "The request body is larger than this route accepts.",
                  "media_type_unsupported": "This route does not accept that Content-Type.",
                  "idempotency_key_reused": "This Idempotency-Key was used for a different request.",
                  "precondition_required": "This route requires an If-Match header.",
                  "rate_limit_exceeded": "Too many requests; try again later.",
                  "internal_error": "Something went wrong on our side.",
                  "upstream_error": "A service XipID depends on failed.",
                  "service_unavailable": "The service is temporarily unavailable.",
                  "upstream_timeout": "A service XipID depends on did not answer in time.",
                  "challenge_closed": "The challenge is already closed.",
                  "invitation_changed": "The brand changed what it asks after the invitation was read.",
                  "delegation_changed": "The agent's request changed or closed after it was read.",
                  "agent_version_taken": "An agent of the org has that key and version.",
                  "subject_scopes_accepted": "The person accepted the scopes first asked, and asking for others needs their consent again.",
                  "brand_slug_taken": "A brand with that slug exists.",
                  "email_reserved": "The address belongs to a XipID staff account.",
                  "reference_face_on_file": "The person has a face on file that this brand did not enroll, and it stays.",
                  "subject_unlinked": "The pairwise identifier names no person linked to this brand, or to a brand of this agent's org.",
                  "consent_missing": "The person has not granted this brand, or this agent, their presence.",
                  "channel_unavailable": "The person has no phone XipID may text.",
                  "reference_face_missing": "The person has no face on file.",
                  "reference_face_unusable": "The image cannot be a reference face.",
                  "callback_url_refused": "No outcome can be posted to that callback URL.",
                  "text_failed": "The provider refused the text.",
                  "email_failed": "The provider refused the email.",
                  "code_invalid": "That code is not right.",
                  "code_expired": "The code expired or has no tries left.",
                  "code_used": "The code was already used.",
                  "code_resend_too_soon": "A code was sent too recently to send another.",
                  "registration_expired": "The registration expired.",
                  "test_identity_refused": "The address or number is reserved for testing, which production refuses.",
                  "link_expired": "The request the link opens is closed.",
                  "link_used": "The link was already opened in another browser.",
                  "decline_not_allowed": "The request's policy does not allow a decline.",
                  "selfie_limit_reached": "The hour's selfies are used up.",
                  "document_limit_reached": "The day's document reads are used up.",
                  "owner_required": "The org must keep an owner: hand the ownership to another member first.",
                  "member_exists": "That XipID is already a member of the org.",
                  "member_invitation_closed": "The invitation was accepted, was withdrawn, or is past its 7 days.",
                  "member_invitation_other_address": "The invitation went to another address than the one this XipID verified."
                }
              },
              "message": {
                "type": "string",
                "description": "XipID's sentence, for a person; never branch on it."
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string"
                    },
                    "code": {
                      "type": "string",
                      "enum": [
                        "required",
                        "unknown",
                        "invalid_type",
                        "invalid_format",
                        "invalid_value",
                        "too_small",
                        "too_big"
                      ],
                      "description": "What is wrong with the member.",
                      "x-enumDescriptions": {
                        "required": "It is missing.",
                        "unknown": "The route does not take it.",
                        "invalid_type": "It is of another type.",
                        "invalid_format": "It is not in the format it must be in.",
                        "invalid_value": "It is none of the values it may be.",
                        "too_small": "It is under its minimum.",
                        "too_big": "It is over its maximum."
                      }
                    },
                    "message": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "path",
                    "code",
                    "message"
                  ]
                },
                "description": "One entry for each problem with the request."
              },
              "request_id": {
                "type": "string",
                "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$",
                "description": "The request, as `X-Request-Id` names it."
              },
              "doc_url": {
                "type": "string",
                "description": "The code's page."
              },
              "valid_versions": {
                "description": "Carried by `version_invalid`.",
                "type": "array",
                "items": {
                  "type": "string"
                }
              },
              "challenge_id": {
                "description": "Carried by `text_failed`, `subject_unlinked`, `consent_missing`.",
                "type": "string",
                "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
              },
              "provider": {
                "description": "Carried by `text_failed`, `email_failed`.",
                "type": "string"
              },
              "provider_code": {
                "description": "Carried by `text_failed`.",
                "type": "integer",
                "minimum": -9007199254740991,
                "maximum": 9007199254740991
              },
              "pairwise_id": {
                "description": "Carried by `subject_unlinked`, `consent_missing`, `channel_unavailable`, `reference_face_missing`.",
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{22}$"
              },
              "reason": {
                "description": "Carried by `reference_face_unusable`.",
                "type": "string",
                "enum": [
                  "unsupported_format",
                  "no_face",
                  "multiple_faces"
                ],
                "x-enumDescriptions": {
                  "unsupported_format": "The image is neither a JPEG nor a PNG.",
                  "no_face": "The image holds no face.",
                  "multiple_faces": "The image holds more than one face."
                }
              },
              "attempts_left": {
                "description": "Carried by `code_invalid`.",
                "type": "integer",
                "minimum": 0,
                "maximum": 9007199254740991
              },
              "try_again_at": {
                "description": "Carried by `code_resend_too_soon`, `selfie_limit_reached`, `document_limit_reached`.",
                "type": "string",
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d\\.\\d{3}(?:Z))$"
              }
            },
            "required": [
              "code",
              "message",
              "details",
              "request_id",
              "doc_url"
            ]
          }
        },
        "required": [
          "error"
        ]
      },
      "CreateChallenge": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "object",
            "properties": {
              "pairwise_id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{22}$"
              }
            },
            "required": [
              "pairwise_id"
            ],
            "additionalProperties": false
          },
          "request": {
            "type": "object",
            "properties": {
              "type": {
                "type": "string",
                "enum": [
                  "wire",
                  "beneficiary_change",
                  "withdrawal",
                  "password_reset",
                  "address_change",
                  "other"
                ],
                "description": "What the brand asks the person to approve.",
                "x-enumDescriptions": {
                  "wire": "A wire transfer.",
                  "beneficiary_change": "A change to whom a payment goes.",
                  "withdrawal": "A withdrawal of funds.",
                  "password_reset": "A reset of a password.",
                  "address_change": "A change of address.",
                  "other": "Anything else; the title says what."
                }
              },
              "title": {
                "type": "string",
                "minLength": 1,
                "maxLength": 120
              },
              "summary": {
                "type": "string",
                "maxLength": 280
              },
              "money": {
                "type": "object",
                "properties": {
                  "amount_minor": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 9007199254740991
                  },
                  "currency": {
                    "type": "string",
                    "pattern": "^[A-Z]{3}$"
                  }
                },
                "required": [
                  "amount_minor",
                  "currency"
                ],
                "additionalProperties": false
              },
              "counterparty": {
                "type": "string",
                "maxLength": 200
              },
              "reference": {
                "type": "string",
                "maxLength": 120
              },
              "requested_at": {
                "type": "string",
                "maxLength": 35,
                "format": "date-time",
                "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
              }
            },
            "required": [
              "type",
              "title",
              "requested_at"
            ],
            "additionalProperties": false
          },
          "policy": {
            "type": "object",
            "properties": {
              "checks": {
                "maxItems": 2,
                "type": "array",
                "items": {
                  "type": "string",
                  "enum": [
                    "liveness",
                    "face_match"
                  ],
                  "description": "A check the page runs before an approval counts.",
                  "x-enumDescriptions": {
                    "liveness": "The selfie is of a live person at the phone, not a photo or a recording.",
                    "face_match": "The selfie's face matches the person's reference face."
                  }
                },
                "uniqueItems": true
              },
              "allow_decline": {
                "type": "boolean"
              },
              "allow_note": {
                "type": "boolean"
              },
              "expires_in_seconds": {
                "type": "integer",
                "minimum": 60,
                "maximum": 3600
              }
            },
            "additionalProperties": false
          },
          "callback": {
            "type": "object",
            "properties": {
              "url": {
                "type": "string",
                "maxLength": 2048,
                "format": "uri"
              }
            },
            "required": [
              "url"
            ],
            "additionalProperties": false
          },
          "metadata": {
            "type": "object",
            "propertyNames": {
              "type": "string",
              "maxLength": 40
            },
            "additionalProperties": {
              "type": "string",
              "maxLength": 500
            },
            "maxProperties": 50
          }
        },
        "required": [
          "subject",
          "request",
          "callback"
        ],
        "additionalProperties": false
      },
      "CreateSubject": {
        "type": "object",
        "properties": {
          "reference": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "display_name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "channel": {
            "oneOf": [
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "phone"
                  },
                  "to": {
                    "type": "string",
                    "pattern": "^\\+[1-9]\\d{6,14}$"
                  }
                },
                "required": [
                  "type",
                  "to"
                ],
                "additionalProperties": false,
                "description": "A phone number in E.164, which XipID never texts: the brand may deliver the `invite_url` on its own channel."
              },
              {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "const": "email"
                  },
                  "to": {
                    "type": "string",
                    "maxLength": 254,
                    "format": "email",
                    "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
                  }
                },
                "required": [
                  "type",
                  "to"
                ],
                "additionalProperties": false,
                "description": "An email address, which XipID emails the invitation."
              }
            ]
          },
          "scopes": {
            "minItems": 1,
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "attribute": {
                  "type": "string",
                  "enum": [
                    "presence",
                    "name",
                    "date_of_birth",
                    "email",
                    "phone",
                    "address",
                    "tier",
                    "ssn_match"
                  ],
                  "description": "What the scope lets the brand do with the person.",
                  "x-enumDescriptions": {
                    "presence": "Ask them to confirm it is really them, by a challenge.",
                    "name": "See their name.",
                    "date_of_birth": "See their date of birth.",
                    "email": "See their email address.",
                    "phone": "See their phone number.",
                    "address": "See their address.",
                    "tier": "See their verification tier.",
                    "ssn_match": "Check that a Social Security number the brand holds is theirs."
                  }
                },
                "purpose": {
                  "type": "string",
                  "pattern": "^[a-z][a-z0-9_]{2,39}$"
                }
              },
              "required": [
                "attribute",
                "purpose"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "reference",
          "channel",
          "scopes"
        ],
        "additionalProperties": false
      },
      "SearchSubjects": {
        "type": "object",
        "properties": {
          "reference": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128
          },
          "limit": {
            "default": 20,
            "description": "How many items the page holds.",
            "type": "integer",
            "minimum": 1,
            "maximum": 100
          },
          "starting_after": {
            "description": "The page after the item a page's `next_cursor` named.",
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{1,512}$"
          },
          "ending_before": {
            "description": "The page before the item a page's `previous_cursor` named; not with `starting_after`.",
            "type": "string",
            "pattern": "^[A-Za-z0-9_-]{1,512}$"
          }
        },
        "required": [
          "reference"
        ],
        "additionalProperties": false
      },
      "EnrollReferenceFace": {
        "type": "object",
        "properties": {
          "image": {
            "type": "string",
            "minLength": 1,
            "maxLength": 5592408,
            "format": "base64",
            "contentEncoding": "base64",
            "pattern": "^$|^(?:[0-9a-zA-Z+/]{4})*(?:(?:[0-9a-zA-Z+/]{2}==)|(?:[0-9a-zA-Z+/]{3}=))?$"
          }
        },
        "required": [
          "image"
        ],
        "additionalProperties": false
      },
      "CreateDelegation": {
        "type": "object",
        "properties": {
          "subject": {
            "type": "object",
            "properties": {
              "pairwise_id": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]{22}$"
              }
            },
            "required": [
              "pairwise_id"
            ],
            "additionalProperties": false
          },
          "scopes": {
            "minItems": 1,
            "maxItems": 20,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "attribute": {
                  "type": "string",
                  "enum": [
                    "presence"
                  ],
                  "description": "What the delegation lets the agent do with the person.",
                  "x-enumDescriptions": {
                    "presence": "Ask them to confirm it is really them, by a challenge."
                  }
                },
                "purpose": {
                  "type": "string",
                  "pattern": "^[a-z][a-z0-9_]{2,39}$"
                }
              },
              "required": [
                "attribute",
                "purpose"
              ],
              "additionalProperties": false
            }
          },
          "ends_at": {
            "type": "string",
            "maxLength": 35,
            "format": "date-time",
            "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
          }
        },
        "required": [
          "subject",
          "scopes",
          "ends_at"
        ],
        "additionalProperties": false
      }
    },
    "parameters": {
      "XipVersion": {
        "name": "Xip-Version",
        "in": "header",
        "required": false,
        "description": "The version to answer in; when absent, the version the brand's org is pinned to.",
        "schema": {
          "type": "string",
          "enum": [
            "2026-09-26"
          ],
          "description": "A released version of the API, named by the day its contract was fixed.",
          "x-enumDescriptions": {
            "2026-09-26": "The first version: challenges, subjects and events, and the signed outcome."
          }
        }
      }
    },
    "headers": {
      "X-Request-Id": {
        "description": "The id XipID gave the request, which an error names as `request_id`.",
        "schema": {
          "type": "string",
          "pattern": "^[0-9A-HJKMNP-TV-Z]{26}$"
        }
      },
      "Xip-Version": {
        "description": "The version the answer is in.",
        "schema": {
          "type": "string",
          "enum": [
            "2026-09-26"
          ],
          "description": "A released version of the API, named by the day its contract was fixed.",
          "x-enumDescriptions": {
            "2026-09-26": "The first version: challenges, subjects and events, and the signed outcome."
          }
        }
      },
      "X-RateLimit-Limit": {
        "description": "The requests the tightest limit the request counted against allows in its period.",
        "schema": {
          "type": "integer",
          "minimum": 1
        }
      },
      "X-RateLimit-Remaining": {
        "description": "How many more requests it admits now.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "X-RateLimit-Reset": {
        "description": "The seconds until it is full again.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "Retry-After": {
        "description": "The seconds to wait before trying again.",
        "schema": {
          "type": "integer",
          "minimum": 0
        }
      },
      "Location": {
        "description": "The path of what the request made, or of where its work is followed.",
        "schema": {
          "type": "string"
        }
      },
      "ETag": {
        "description": "The subject's strong entity tag, which `If-Match` may send back.",
        "schema": {
          "type": "string"
        }
      }
    },
    "securitySchemes": {
      "apiKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "An API key of the brand, `xid_key_live_` or `xid_key_test_` and 32 characters, sent as a bearer token. A key opens every operation a brand may call while its org is live; it carries no scopes."
      },
      "agentCredential": {
        "type": "http",
        "scheme": "bearer",
        "description": "A credential of an org's agent, `xid_agent_live_` or `xid_agent_test_` and 32 characters, sent as a bearer token. It opens every operation an agent may call while the agent is active and its org live; it carries no scopes."
      }
    }
  }
}
