{"basePath":"/v1","info":{"title":"Firefox Accounts API Documentation","version":"0.0.1"},"schemes":["https"],"tags":[{"name":"Auth Server API Overview","description":"This document provides protocol-level details of the Firefox Accounts auth server API. For a prose description of the client/server protocol and details on how each parameter is derived, see the [API design document](https://wiki.mozilla.org/Identity/AttachedServices/KeyServerProtocol). For a reference client implementation, see [fxa-auth-client](https://github.com/mozilla/fxa/tree/main/packages/fxa-auth-client).\n\n  ## URL Structure for Auth Server\n  All requests use URLs of the form:\n\n  > `https://<base-URI>/v1/<endpoint-path>`\n\n  Note that:\n\n  - All API access must be over a properly-validated HTTPS connection.\n  - The URL embeds a version identifier `v1`.\n    Future revisions of this API may introduce new version numbers.\n  - The base URI of the server may be configured on a per-client basis:\n    - The canonical URL for Mozilla's hosted Firefox Accounts server\n      is `https://api.accounts.firefox.com/v1`.\n\n  ## Request Format\n  All POST requests must have a content-type of `application/json` with a UTF8-encoded JSON body and must specify the content-length header. Keys and other binary data are included in the JSON as hexadecimal strings.\n\n  The following request headers may be specified to influence the behavior of the server:\n\n  - `Accept-Language` may be used to localize emails and SMS messages.\n\n  ## Response format\n  All requests receive a JSON response body with a `Content-Type: application/json` header and appropriate `Content-Length` set. The body structure depends on the endpoint returning it.\n\n  Successful responses will have an HTTP status code of 200 and a `Timestamp` header that contains the current server time in seconds since the epoch.\n\n  Error responses caused by invalid client behavior will have an HTTP status code in the 4xx range. Error responses caused by server-side problems will have an HTTP status code in the 5xx range. Failures due to invalid behavior from the client.\n\n  To simplify error handling for the client, the type of error is indicated by both\n  a defined HTTP status code and an application-specific `errno` in the body.\n\n  For example:\n\n  ```js\n      {\n        \"code\": 400,  // Matches the HTTP status code\n        \"errno\": 107, // Stable application-level error number\n        \"error\": \"Bad Request\", // String description of the error type\n        \"message\": \"Invalid parameter in request body\", // Specific error message\n        \"info\": \"https://docs.dev.lcip.og/errors/1234\"  // Link to more information\n      }\n  ```\n\n  Responses for some errors may include additional parameters.\n\n\n  ### Defined errors\n\n  The currently-defined values for `code` and `errno` are:\n\n  | status code | errno | description                                                                   |\n  |-------------|-------|-------------------------------------------------------------------------------|\n  | 400         | 100   | Incorrect Database Patch Level                                                |\n  | 400         | 101   | Account already exists                                                        |\n  | 400         | 102   | Unknown account                                                               |\n  | 400         | 103   | Incorrect password                                                            |\n  | 400         | 104   | Unconfirmed account                                                            |\n  | 400         | 105   | Invalid confirmation code                                                   |\n  | 400         | 106   | Invalid JSON in request body                                                  |\n  | 400         | 107   | Invalid parameter in request body                                             |\n  | 400         | 108   | Missing parameter in request body                                             |\n  | 401         | 109   | Invalid request signature                                                     |\n  | 401         | 110   | Invalid authentication token in request signature                             |\n  | 401         | 111   | Invalid timestamp in request signature                                        |\n  | 411         | 112   | Missing content-length header                                                 |\n  | 413         | 113   | Request body too large                                                        |\n  | 429         | 114   | Client has sent too many requests                                             |\n  | 401         | 115   | Invalid nonce in request signature                                            |\n  | 410         | 116   | This endpoint is no longer supported                                          |\n  | 400         | 120   | Incorrect email case                                                          |\n  | 400         | 123   | Unknown device                                                                |\n  | 400         | 124   | Session already registered by another device                                  |\n  | 400         | 125   | The request was blocked for security reasons                                  |\n  | 400         | 126   | Account must be reset                                                         |\n  | 400         | 127   | Invalid unblock code                                                          |\n  | 400         | 129   | Invalid phone number                                                          |\n  | 400         | 130   | Invalid region                                                                |\n  | 400         | 131   | Invalid message id                                                            |\n  | 500         | 132   | Message rejected                                                              |\n  | 400         | 133   | Email account sent complaint                                                  |\n  | 400         | 134   | Email account hard bounced                                                    |\n  | 400         | 135   | Email account soft bounced                                                    |\n  | 400         | 136   | Email already exists                                                          |\n  | 400         | 137   | Can not delete primary email                                                  |\n  | 400         | 138   | Unverified session                                                            |\n  | 400         | 139   | Can not add secondary email that is same as your primary                      |\n  | 400         | 140   | Email already exists                                                          |\n  | 400         | 141   | Email already exists                                                          |\n  | 400         | 142   | Sign in with this email type is not currently supported                       |\n  | 400         | 143   | Unknown email                                                                 |\n  | 400         | 144   | Email already exists                                                          |\n  | 400         | 145   | Reset password with this email type is not currently supported                |\n  | 400         | 146   | Invalid signin code                                                           |\n  | 400         | 147   | Can not change primary email to an unverified email                           |\n  | 400         | 148   | Can not change primary email to an email that does not belong to this account |\n  | 400         | 149   | This email can not currently be used to login                                 |\n  | 400         | 150   | Can not resend email code to an email that does not belong to this account    |\n  | 500         | 151   | Failed to send email                                                          |\n  | 422         | 151   | Failed to send email                                                          |\n  | 400         | 152   | Invalid token confirmation code                                               |\n  | 400         | 153   | Expired token confirmation code                                               |\n  | 400         | 154   | TOTP token already exists for this account.                                   |\n  | 400         | 155   | TOTP token not found.                                                         |\n  | 400         | 156   | Backup authentication code not found.                                         |\n  | 400         | 157   | Unavailable device command.                                                   |\n  | 400         | 158   | Account recovery key not found.                                               |\n  | 400         | 159   | Account recovery key is not valid.                                            |\n  | 400         | 160   | This request requires two step authentication enabled on your account.        |\n  | 400         | 161   | Account recovery key already exists.                                          |\n  | 400         | 162   | Unknown client_id                                                             |\n  | 400         | 164   | Stale auth timestamp                                                          |\n  | 409         | 165   | Redis WATCH detected a conflicting update                                     |\n  | 400         | 166   | Not a public client                                                           |\n  | 400         | 167   | Incorrect redirect URI                                                        |\n  | 400         | 168   | Invalid response_type                                                         |\n  | 400         | 169   | Public clients require PKCE OAuth parameters                                  |\n  | 400         | 170   | Required Authentication Context Reference values could not be satisfied       |\n  | 400         | 171   | Incorrect client_secret                                                       |\n  | 400         | 172   | Unknown authorization code                                                    |\n  | 400         | 173   | Mismatched authorization code                                                 |\n  | 400         | 174   | Expired authorization code                                                    |\n  | 400         | 175   | Public clients require PKCE OAuth parameters                                  |\n  | 404         | 176   | Unknown customer                                                              |\n  | 404         | 177   | Unknown subscription                                                          |\n  | 400         | 178   | Unknown subscription plan                                                     |\n  | 400         | 179   | Subscription payment token rejected                                           |\n  | 400         | 180   | Subscription has already been cancelled                                       |\n  | 400         | 181   | Customer update rejected                                                      |\n  | 400         | 182   | Unknown refresh token                                                         |\n  | 400         | 183   | Invalid or expired confirmation code                                          |\n  | 400         | 184   | Subscription has already been cancelled                                       |\n  | 400         | 185   | Subscription plan is not a valid update                                       |\n  | 400         | 186   | Payment method failed                                                         |\n  | 409         | 187   | User already subscribed                                                       |\n  | 500         | 188   | Failed to find a subscription associated with Stripe source                   |\n  | 400         | 192   | Billing agreement already on file for this customer                           |\n  | 400         | 193   | PayPal payment token is missing                                               |\n  | 400         | 194   | PayPal billing agreement is missing for the existing subscriber               |\n  | 400         | 195   | Account for this email has an active subscription                             |\n  | 400         | 196   | Invalid token                                                                 |\n  | 500         | 197   | IAP Internal Error                                                            |\n  | 404         | 198   | Unknown app name                                                              |\n  | 400         | 199   | Invalid promotion code                                                        |\n  | 503         | 201   | Service unavailable                                                           |\n  | 403         | 202   | Feature not enabled                                                           |\n  | 500         | 203   | System unavailable, try again soon                                            |\n  | 503         | 204   | This client has been temporarily disabled                                     |\n  | 500         | 205   | Could not login with third party account, please try again later              |\n  | 400         | 206   | Can not create password, password already set.                                |\n  | 400         | 207   | Account creation rejected.                                                    |\n  | 403         | 208   | Purchase has been registered to another user.                                 |\n  | 500         | 998   | An internal validation check failed.                                          |\n\n  The following errors include additional response properties:\n\n  | errno | description                                                             |\n  |-------|-------------------------------------------------------------------------|\n  | 100   | level, levelRequired                                                    |\n  | 101   | email                                                                   |\n  | 102   | email                                                                   |\n  | 103   | email                                                                   |\n  | 105   |                                                                         |\n  | 107   | validation                                                              |\n  | 108   | param                                                                   |\n  | 111   | serverTime                                                              |\n  | 114   | retryAfter, retryAfterLocalized, verificationMethod, verificationReason |\n  | 120   | email                                                                   |\n  | 124   | deviceId                                                                |\n  | 125   | verificationMethod, verificationReason                                  |\n  | 126   | email                                                                   |\n  | 130   | region                                                                  |\n  | 132   | reason, reasonCode                                                      |\n  | 133   | bouncedAt                                                               |\n  | 134   | bouncedAt                                                               |\n  | 135   | bouncedAt                                                               |\n  | 152   |                                                                         |\n  | 153   |                                                                         |\n  | 162   | clientId                                                                |\n  | 164   | authAt                                                                  |\n  | 167   | redirectUri                                                             |\n  | 169   | invalidScopes                                                           |\n  | 171   | foundValue                                                              |\n  | 201   | retryAfter                                                              |\n  | 202   | retryAfter                                                              |\n  | 203   | service, operation                                                      |\n  | 998   | op, data                                                                |\n\n\n  ### Responses from intermediary servers\n\n  As with any HTTP-based API, clients must handle standard errors that may be returned by proxies, load-balancers or other intermediary servers. These non-application responses can be identified by the absence of a correctly-formatted JSON response body.\n\n  Common examples include:\n\n  - `413 Request Entity Too Large`: may be returned by an upstream proxy server.\n  - `502 Gateway Timeout`: may be returned if a load-balancer can't connect to application servers.\n\n  ## Validation\n  In the documentation that follows, some properties of requests and responses are validated by common code that has been refactored and extracted. For reference, those common validations are defined here.\n\n\n  ### lib/routes/validators\n\n  - `HEX_STRING`: `/^(?:[a-fA-F0-9]{2})+$/`\n  - `BASE_36`: `/^[a-zA-Z0-9]*$/`\n  - `VALID_SCOPE_VALUE`: `/^[\\x21\\x23-\\x5B\\x5D-\\x7E]+$/`\n  - `URL_SAFE_BASE_64`: `/^[A-Za-z0-9_-]+$/`\n  - `PKCE_CODE_VERIFIER`: `/^[A-Za-z0-9-\\._~]{43,128}$/`\n  - `DISPLAY_SAFE_UNICODE`: `/^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFF])*$/`\n  - `DISPLAY_SAFE_UNICODE_WITH_NON_BMP`: `/^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uE000-\\uF8FF\\uFFF9-\\uFFFF])*$/`\n  - `BEARER_AUTH_REGEX`: `/^Bearer\\s+([a-z0-9+\\/]+)$/i`\n  - `service`: `string, max(16), regex(/^[a-zA-Z0-9\\-]*$/)`\n  - `hexString`: `string, regex(/^(?:[a-fA-F0-9]{2})+$/)`\n  - `clientId`: `module.exports.hexString.length(16)`\n  - `clientSecret`: `module.exports.hexString`\n  - `accessToken`: `module.exports.hexString.length(64)`\n  - `refreshToken`: `module.exports.hexString.length(64)`\n  - `authorizationCode`: `module.exports.hexString.length(64)`\n  - `scope`: `string, max(256), regex(/^[a-zA-Z0-9 _\\/.:-]*$/), allow('')`\n  - `storedScope`: `string, max(256), regex(VALID_SCOPE_VALUE), allow('')`\n  - `assertion`: `string, min(50), max(10240), regex(/^[a-zA-Z0-9_\\-\\.~=]+$/)`\n  - `pkceCodeChallengeMethod`: `string, valid('S256')`\n  - `pkceCodeChallenge`: `string, length(43), regex(module, exports.URL_SAFE_BASE_64)`\n  - `pkceCodeVerifier`: `string, length(43), regex(module, exports.PKCE_CODE_VERIFIER)`\n  - `jwe`: `string, max(1024), regex(/^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$/)`\n  - `verificationMethod`: `string, valid()`\n  - `authPW`: `string, length(64), regex(HEX_STRING), required`\n  - `wrapKb`: `string, length(64), regex(/^(?:[a-fA-F0-9]{2})+$/)`\n  - `recoveryKeyId`: `string, regex(HEX_STRING), max(32)`\n  - `recoveryData`: `string, regex(/[a-zA-Z0-9.]/), max(1024), required`\n  - `E164_NUMBER`: `/^\\+[1-9]\\d{1,14}$/`\n  - `DIGITS`: `/^[0-9]+$/`\n  - `DEVICE_COMMAND_NAME`: `/^(?!(?:__proto__|constructor|prototype)$)[a-zA-Z0-9._\\/\\-:]{1,100}$/`\n  - `IP_ADDRESS`: `string, ip`\n\n\n  ### lib/metrics/context\n\n  - `SCHEMA`: object({\n    - `deviceId`: string, length(32), regex(HEX_STRING), optional\n    - `entrypoint`: ENTRYPOINT_SCHEMA.optional\n    - `entrypointExperiment`: ENTRYPOINT_SCHEMA.optional\n    - `entrypointVariation`: ENTRYPOINT_SCHEMA.optional\n    - `flowId`: string, length(64), regex(HEX_STRING), optional\n    - `flowBeginTime`: number, integer, positive, optional\n    - `utmCampaign`: UTM_CAMPAIGN_SCHEMA.optional\n    - `utmContent`: UTM_SCHEMA.optional\n    - `utmMedium`: UTM_SCHEMA.optional\n    - `utmSource`: UTM_SCHEMA.optional\n    - `utmTerm`: UTM_SCHEMA.optional\n      }), unknown(false), and('flowId', 'flowBeginTime')\n  - `schema`: SCHEMA.optional\n  - `requiredSchema`: SCHEMA.required\n\n\n  ### lib/features\n\n  - `schema`: array, items(string), optional\n\n\n  ### lib/devices\n\n  - `schema`: {\n\n    - `id`: isA.string.length(32).regex(HEX_STRING)\n    - `location`: isA.object({\n      - `city`: isA.string.optional.allow(null)\n      - `country`: isA.string.optional.allow(null)\n      - `state`: isA.string.optional.allow(null)\n      - `stateCode`: isA.string.optional.allow(null)\n      - })\n    - `name`: isA.string.max(255).regex(DISPLAY_SAFE_UNICODE_WITH_NON_BMP)\n    - `nameResponse`: isA.string.max(255).allow('')\n    - `type`: isA.string.max(16)\n    - `pushCallback`: validators.pushCallbackUrl({ scheme: 'https' }).regex(PUSH_SERVER_REGEX).max(255).allow('')\n    - `pushPublicKey`: isA.string.max(88).regex(URL_SAFE_BASE_64).allow('')\n    - `pushAuthKey`: isA.string.max(24).regex(URL_SAFE_BASE_64).allow('')\n    - `pushEndpointExpired`: isA.boolean.strict\n    - `availableCommands`: isA.object.pattern(validators.DEVICE_COMMAND_NAME\n    - `isA.string.max(2048))\n\n    }\n\n  ## Back-off protocol\n\n  During periods of heavy load, the server may request that clients enter a \"back-off\" state,\n  in which they avoid making further requests.\n\n  At such times,\n  it will return a `503 Service Unavailable` response\n  with a `Retry-After` header denoting the number of seconds to wait\n  before issuing any further requests.\n  It will also include `errno: 201`\n  and a `retryAfter` field\n  matching the value of the `Retry-After` header\n  in the body.\n\n  For example,\n  the following response indicates that the client\n  should suspend making further requests\n  for 30 seconds:\n\n  ```js\n      HTTP/1.1 503 Service Unavailable\n      Retry-After: 30\n      Content-Type: application/json\n\n      {\n          \"code\": 503,\n          \"errno\": 201,\n          \"error\": \"Service Unavailable\",\n          \"message\": \"Service unavailable\",\n          \"info\": \"https://mozilla.github.io/ecosystem-platform/api#section/Response-format\",\n          \"retryAfter\": 30,\n          \"retryAfterLocalized\": \"in a few seconds\"\n      }\n```\n\n  Rate limiting uses the same shape with `429 Too Many Requests` and\n  `errno: 114`. On those responses `retryAfter` is in **milliseconds**;\n  the `Retry-After` header is in seconds, as always."},{"name":"OAuth Server API Overview","description":"## URL Structure for OAuth Server\n> `https://<server-url>/v1/<api-endpoint>`\n\nNote that:\n- All API access must be over HTTPS\n- The URL embeds a version identifier \"v1\"; future versions of this API may introduce new version numbers.\n- The base URL of the server may be configured on a per-client basis.\n\n## Errors\nInvalid requests will return 4XX responses. Internal failures will return 5XX. Both will include JSON responses describing the error.\n\n**Example error:**\n\n```js\n    {\n      \"code\": 400, // matches the HTTP status code\n      \"errno\": 101, // stable application-level error number\n      \"error\": \"Bad Request\", // string description of error type\n      \"message\": \"Unknown client\"\n    }\n```\n\nThe currently-defined error responses are:\n\n| status code | errno | description                                     |\n|-------------|-------|-------------------------------------------------|\n| 400         | 101   | unknown client id                               |\n| 400         | 102   | incorrect client secret                         |\n| 400         | 103   | `redirect_uri` doesn't match registered value |\n| 401         | 104   | invalid fxa assertion                           |\n| 400         | 105   | unknown code                                    |\n| 400         | 106   | incorrect code                                  |\n| 400         | 107   | expired code                                    |\n| 400         | 108   | invalid token                                   |\n| 400         | 109   | invalid request parameter                       |\n| 400         | 110   | invalid response_type                           |\n| 401         | 111   | unauthorized                                    |\n| 403         | 112   | forbidden                                       |\n| 415         | 113   | invalid content type                            |\n| 400         | 114   | invalid scopes                                  |\n| 400         | 115   | expired token                                   |\n| 400         | 116   | not a public client                             |\n| 400         | 117   | incorrect code_challenge                        |\n| 400         | 118   | pkce parameters missing                         |\n| 400         | 119   | stale authentication timestamp                  |\n| 400         | 120   | mismatch acr value                              |\n| 400         | 121   | invalid grant_type                              |\n| 400         | 170   | unmet `acr_values` or `max_age` requirement   |\n| 500         | 999   | internal server error                           |\n\n\n## API Endpoints\n- [GET /v1/authorization](#tag/OAuth-Server-API-Overview/operation/getAuthorization)\n- [POST /v1/authorization](#tag/OAuth-Server-API-Overview/operation/postAuthorization)\n- [GET /v1/client/:id](#tag/OAuth-Server-API-Overview/operation/getClientClient_id)\n- [POST /v1/destroy](#tag/OAuth-Server-API-Overview/operation/postDestroy)\n- [POST /v1/introspect](#tag/OAuth-Server-API-Overview/operation/postIntrospect)\n- [GET /v1/jwks](#tag/OAuth-Server-API-Overview/operation/getJwks)\n- [POST /v1/token](#tag/OAuth-Server-API-Overview/operation/postToken)\n- [POST /v1/verify](#tag/OAuth-Server-API-Overview/operation/postVerify)"}],"x-tagGroups":[{"name":"Firefox Accounts Auth Server API","tags":["Auth Server API Overview","Account","Account recovery key","Backup authentication codes","Recovery phone","Devices and Sessions","Emails","Miscellaneous","Oauth","Password","Security events","Session","Sign","Subscriptions","Third Party Authentication","totp","Unblock codes","Util"]},{"name":"Firefox Accounts OAuth Server API","tags":["OAuth Server API Overview"]}],"swagger":"2.0","host":"api.accounts.firefox.com","paths":{"/.well-known/public-keys":{"get":{"summary":"/.well-known/public-keys","operationId":"getWellknownPublickeys","description":"Used by clients to generate JSON web tokens, and allows FxA to verify those tokens.","tags":["Miscellaneous"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/account":{"get":{"summary":"/account","operationId":"getAccount","description":"🔒 Authenticated with session token\n\nReturns account data including subscriptions.","tags":["Miscellaneous"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model8"},"description":"Successful"}}}},"/authorization":{"get":{"summary":"/v1/authorization","operationId":"getAuthorization","description":"This endpoint starts the OAuth flow. A client redirects the user agent to this url. This endpoint will then redirect to the appropriate content-server page.\n\n**Step-up authentication.** A client may require the user to have completed a second factor,\nor to have authenticated recently, by supplying `acr_values` and/or `max_age`\n([RFC 9470](https://datatracker.ietf.org/doc/html/rfc9470) section 5). `acr_values=AAL2`\nrequires an authenticator assurance level of 2; `AAL2` is the only value recognized and any\nother value in the list is ignored. `max_age` bounds, in seconds, how old the session's most\nrecent authentication event may be, evaluated with a five-second grace period so that a\njust-completed challenge satisfies `max_age=0`. If either requirement is unmet the request\nfails with errno 170 and the hosted sign-in UI challenges the user for a second factor before\nretrying. Where it cannot challenge — the RP also sent `prompt=none` — the UI instead\nredirects to the registered `redirect_uri` with\n`error=unmet_authentication_requirements`.\n\nThe resulting grant carries `acr` and `auth_time` on the ID token and the JWT access\ntoken, and `acr`, `auth_time` and `amr` via the `/v1/introspect` endpoint. These are not carried by\nrefresh tokens, so an elevated authentication does not survive a token refresh.","tags":["OAuth Server API Overview"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}},"x-codeSamples":[{"lang":"JavaScript","source":"curl -v \"https://oauth.accounts.firefox.com/v1/authorization?client_id=5901bd09376fadaa&state=1234&scope=profile:email&action=signup\""}]},"post":{"summary":"/v1/authorization","operationId":"postAuthorization","description":"This endpoint should be used by the fxa-content-server, requesting that we supply a short-lived code (currently 15 minutes) that will be sent back to the client. This code will be traded for a token at the [token][] endpoint.\n\n**Step-up authentication.** A client may require the user to have completed a second factor,\nor to have authenticated recently, by supplying `acr_values` and/or `max_age`\n([RFC 9470](https://datatracker.ietf.org/doc/html/rfc9470) section 5). `acr_values=AAL2`\nrequires an authenticator assurance level of 2; `AAL2` is the only value recognized and any\nother value in the list is ignored. `max_age` bounds, in seconds, how old the session's most\nrecent authentication event may be, evaluated with a five-second grace period so that a\njust-completed challenge satisfies `max_age=0`. If either requirement is unmet the request\nfails with errno 170 and the hosted sign-in UI challenges the user for a second factor before\nretrying. Where it cannot challenge — the RP also sent `prompt=none` — the UI instead\nredirects to the registered `redirect_uri` with\n`error=unmet_authentication_requirements`.\n\nThe resulting grant carries `acr` and `auth_time` on the ID token and the JWT access\ntoken, and `acr`, `auth_time` and `amr` via the `/v1/introspect` endpoint. These are not carried by\nrefresh tokens, so an elevated authentication does not survive a token refresh.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model36"}}],"tags":["OAuth Server API Overview"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model37"},"description":"A valid request will return a 200 response, with JSON containing the `redirect` to follow.\n<br />\n**Example:**\n\n```js\n    {\n      \"redirect\": \"https://example.domain/path?foo=bar&code=4ab433e31ef3a7cf7c20590f047987922b5c9ceb1faff56f0f8164df053dd94c&state=1234\"\n    }\n```\n\n**Implicit Grant** \\\n If requesting an implicit grant (token), the response will match the [/v1/token][token] response."}},"x-codeSamples":[{"lang":"JavaScript","source":"curl -v \\\n -X POST \\\n -H \"Content-Type: application/json\" \\\n \"https://oauth.accounts.firefox.com/v1/authorization\" \\\n -d '{\n  \"client_id\": \"5901bd09376fadaa\",\n  \"assertion\": \"<assertion>\",\n  \"state\": \"1234\",\n  \"scope\": \"profile:email\"\n}'"}]}},"/jwks":{"get":{"summary":"/v1/jwks","operationId":"getJwks","description":"This endpoint returns the [JWKs](https://datatracker.ietf.org/doc/html/rfc7517) that are used for signing OpenID Connect id tokens.","tags":["OAuth Server API Overview"],"responses":{"200":{"description":"A valid response will return JSON of the `keys`.\n<br />\n**Example:**\n``` js\n    {\n      \"keys\": [\n        \"alg\": \"RS256\",\n        \"use\": \"sig\",\n        \"kty\": \"RSA\",\n        \"kid\": \"2015.12.02-1\",\n        \"n\":\"xaQHsKpu1KSK-YEMoLzZS7Xxciy3esGrhrrqW_JBrq3IRmeGLaqlE80zcpIVnStyp9tbet2niYTemt8ug591YWO5Y-S0EgQyFTxnGjzNOvAL6Cd2iGie9QeSehfFLNyRPdQiadYw07fw-h5gweMpVJs8nTgS-Bcorlw9JQM6Il1cUpbP0Lt-F_5qrzlaOiTEAAb4JGOusVh0n-MZfKt7w0mikauMH5KfhflwQDn4YTzRkWJzlldXr1Cs0ZkYzOwS4Hcoku7vd6lqCUO0GgZvkuvCFqdVKzpa4CGboNdfIjcGVF4f1CTQaQ0ao51cwLzq1pgi5aWYhVH7lJcm6O_BQw\",\n        \"e\":\"AQAC\"\n      ]\n    }\n```","schema":{"type":"string"}}},"x-codeSamples":[{"lang":"JavaScript","source":"curl -v \"http://oauth.accounts.firefox.com/v1/jwks\""}]}},"/passkeys":{"get":{"summary":"/passkeys","operationId":"getPasskeys","description":"🔒 Authenticated with session token (verified)\n\nReturns the list of passkeys registered for the authenticated user.\nThe `publicKey` and `signCount` fields are intentionally excluded\nfrom the response as they are internal implementation details.\n\n**Response:** Array of passkey metadata objects, each containing\n`credentialId`, `name`, `createdAt`, `lastUsedAt`, `transports`, `prfEnabled`,\nand `hasPasswordlessSync` — whether the passkey holds a wrap and can\ntherefore unlock `kB` without a password. Only the routes that list\npasskeys resolve that last field.","tags":["Passkeys"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model9"},"description":"Successful"}}}},"/recoveryCodes":{"get":{"summary":"/recoveryCodes","operationId":"getRecoverycodes","description":"🔒 Authenticated with session token\n\nReturn new backup authentication codes while removing old ones.","tags":["Backup authentication codes"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model10"},"description":"Successful"}}},"post":{"summary":"/recoveryCodes","operationId":"postRecoverycodes","description":"🔒 Authenticated with session token\n\nSet backup authentication codes (intended for initial set up)","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model10"}}],"tags":["Backup authentication codes"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model44"},"description":"Successful"}}},"put":{"summary":"/recoveryCodes","operationId":"putRecoverycodes","description":"🔒 Authenticated with session token\n\nReturn new backup authentication codes while removing old ones.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model10"}}],"tags":["Backup authentication codes"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model196"},"description":"Successful"}}}},"/recovery_emails":{"get":{"summary":"/recovery_emails","operationId":"getRecovery_emails","description":"🔒 Authenticated with session token\n\nReturns an array of objects containing details of the email addresses associated with the logged-in user. Currently, the primary email address is always the one from the `accounts` table.","tags":["Emails"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model12"},"description":"Successful"}}}},"/recovery_phone":{"get":{"summary":"/recovery_phone","operationId":"getRecovery_phone","description":"🔒 Authenticated with session token or password forgot token\n\nReturn whether a recovery phone exists, along with the masked phone number information. The full phone number is never returned.","tags":["Recovery phone"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model13"},"description":"Successful"}}},"delete":{"summary":"/recovery_phone","operationId":"deleteRecovery_phone","description":"🔒 Authenticated with verified session token\n\nRemove the currently configured recovery phone from the account.","tags":["Recovery phone"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/securityEvents":{"get":{"summary":"/securityEvents","operationId":"getSecurityevents","description":"🔒 Authenticated with session token\n\nReturns a list of all security events for a signed in account having `account.create`, `account.login`, `account.reset` events.","tags":["Security events"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/account/attached_clients":{"get":{"summary":"/account/attached_clients","operationId":"getAccountAttached_clients","description":"🔒 Authenticated with session token\n\nReturns an array listing all the clients connected to the authenticated user's account, including devices, OAuth clients, and web sessions.\n\nThis endpoint is primarily designed to power the \"devices and apps\" view on the user's account settings page.\n\nIt will only return active sessions. For example, if a user has signed into a service and then later disconnects from that service via account settings connected devices, they would not appear on this list.\n\nDepending on the type of client, it will have at least one and possibly several of the following properties:\n\n- `clientId`: The OAuth client_id of the connected application.\n- `sessionTokenHandle`: An opaque handle for the `sessionToken` held by that client, if any. The raw `sessionTokenId` is a bearer credential and is never returned.\n- `refreshTokenId`: The id of the OAuth `refreshToken` held by that client, if any.\n- `deviceId`: The id of the client's device record, if it has registered one.\n\nThese identifiers can be passed to [/account/attached_client/destroy](#tag/Devices-and-Sessions/operation/getAccountAttached_clients) in order to disconnect the client.\n\nThis endpoint returns a maximum 500 last used devices and sessions.","parameters":[{"type":"number","description":"Filter device list to only show devices active since UTC timestamp.","name":"filterIdleDevicesTimestamp","in":"query","required":false}],"tags":["Devices and Sessions"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model15"},"description":"Successful"}}}},"/account/attached_oauth_clients":{"get":{"summary":"/account/attached_oauth_clients","operationId":"getAccountAttached_oauth_clients","description":"🔒 Authenticated with session token\n\nReturns an array listing all the OAuth Clients that the authenticated user has connected to their account.\n\nThis will only return active sessions. For example, if a user has signed into a service and then later disconnects from that service via account settings connected devices, they would not appear on this list.\n\nEach OAuth Client will have exactly one record, and include the 'lastAccessTime' property.","tags":["Devices and Sessions"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model17"},"description":"Successful"}}}},"/account/devices":{"get":{"summary":"/account/devices","operationId":"getAccountDevices","description":"🔒 Authenticated with session token or authenticated with OAuth refresh token.\n\nReturns an array of registered device objects for the authenticated user.","parameters":[{"type":"number","description":"Filter device list to only show devices active since UTC timestamp.","name":"filterIdleDevicesTimestamp","in":"query","required":false}],"tags":["Devices and Sessions"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model19"},"description":"Successful"}}}},"/account/emails":{"get":{"summary":"/account/emails","operationId":"getAccountEmails","description":"Returns the current primary email, secondary email, and original email that was used during sign up.","tags":["Account"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model20"},"description":"Successful"}}}},"/account/keys":{"get":{"summary":"/account/keys","operationId":"getAccountKeys","description":"🔒 Authenticated with key fetch token\n\nGet the base-16 bundle of encrypted `kA|wrapKb`. The return value must be decrypted with a key derived from `keyFetchToken`, then `wrapKb` must be further decrypted with a key derived from the user's password.\n\nSince `keyFetchToken` is single-use, this can only be done once per session. Note that `keyFetchToken` is consumed regardless of whether the request succeeds or fails.\n\nThis request will fail unless the account's email address and current session has been verified.","tags":["Account"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model21"},"description":"Successful"},"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 104` - Unverified account"}}}},"/account/profile":{"get":{"summary":"/account/profile","operationId":"getAccountProfile","description":"🔒 Authenticated with OAuth bearer token or authenticated with session token\n\nGet the email and locale of a user.\n\nIf an OAuth bearer token is used, the values returned depend on the scopes that the token is authorized for:\n  - `email` requires `profile:email` scope.\n  - `additionalEmails` requires `profile:additionalEmails` scope. It lists the account's verified secondary email addresses.\n  - `locale` requires `profile:locale` scope.\n  - `authenticationMethods` and `authenticatorAssuranceLevel` require `profile:amr` scope.\n  - `accountDisabledAt` requires `profile:account_disabled_at` scope.\n  - `accountLockedAt` requires `profile:account_locked_at` scope.\n\nThe `profile` scope includes all the above sub-scopes.","tags":["Account"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model22"},"description":"Successful"}}}},"/account/status":{"get":{"summary":"/account/status","operationId":"getAccountStatus","description":"🔒🔓 Optionally authenticated with session token\n\nGets the status of an account.","parameters":[{"type":"string","minLength":32,"maxLength":32,"pattern":"^(?:[a-fA-F0-9]{2})+$","name":"uid","in":"query"}],"tags":["Account"],"responses":{"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 108` - Missing parameter in request body"}}},"post":{"summary":"/account/status","operationId":"postAccountStatus","description":"Gets the status of an account without exposing user data through query params. This endpoint is rate limited.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model64"}}],"tags":["Account"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model65"},"description":"Successful"}}}},"/client/{client_id}":{"get":{"summary":"/v1/client/{client_id}","operationId":"getClientClient_id","description":"This endpoint is for the fxa-content-server to retrieve information about a client to show in its user interface.","parameters":[{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application) asking for permission.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16},"name":"client_id","in":"path","required":true}],"tags":["OAuth Server API Overview"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model23"},"description":"A valid 200 response will be a JSON blob.\n<br />\n**Example:**\n``` js\n    {\n      \"name\": \"Where's My Fox\",\n      \"image_uri\": \"https://mozilla.org/firefox.png\",\n      \"redirect_uri\": \"https://wheres.my.firefox.com/oauth\",\n      \"trusted\": true\n    }\n```"}},"x-codeSamples":[{"lang":"JavaScript","source":"curl -v \"http://oauth.accounts.firefox.com/v1/client/5901bd09376fadaa\""}]}},"/recoveryKey/{recoveryKeyId}":{"get":{"summary":"/recoveryKey/{recoveryKeyId}","operationId":"getRecoverykeyRecoverykeyid","description":"🔒 Authenticated with account reset token<br/><br/>Retrieve the account recovery data associated with the given account recovery key.","parameters":[{"type":"string","maxLength":32,"pattern":"^(?:[a-fA-F0-9]{2})+$","name":"recoveryKeyId","in":"path","required":true}],"tags":["Account recovery key"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/recovery_email/status":{"get":{"summary":"/recovery_email/status","operationId":"getRecovery_emailStatus","description":"🔒 Authenticated with session token\n\nReturns the 'verified' status for the account's recovery email address.\n\nCurrently, each account is associated with exactly one email address. This address must be verified before the account can be used (specifically, `GET /account/keys` will return errors until the address is verified). In the future, this may be expanded to include multiple addresses, and/or alternate types of recovery methods (e.g. SMS). A new API will be provided for this extra functionality.\n\nThis call is used to determine the current state (verified or unverified) of the account. During account creation, until the address is verified, the agent can poll this method to discover when it should proceed with  `GET /account/keys`.","parameters":[{"type":"string","maxLength":16,"name":"reason","in":"query","required":false}],"tags":["Emails"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model24"},"description":"Successful"},"401":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 110` - Invalid authentication token in request signature"}}}},"/session/status":{"get":{"summary":"/session/status","operationId":"getSessionStatus","description":"🔒 Authenticated with session token\n\nReturns a success response if the session token is valid. The response includes detailed information about the session and account state.\n\n\n**Response object:**\n- `state`: Describes the session's verification state.\n- `uid`: Account id\n- `details.accountEmailVerified`: Whether the account's primary email is verified\n- `details.sessionVerificationMethod`: The verification method used for the session (e.g., 'email-2fa', 'totp-2fa'), or null if not verified\n- `details.sessionVerified`: Whether the session token itself is verified (no pending token verification)\n- `details.sessionVerificationMeetsMinimumAAL`: Whether the session's Authentication Assurance Level (AAL) meets or exceeds the account's maximum AAL\n- `details.verified`: Deprecated! Use accountEmailVerified and sessionVerified instead.","tags":["Session"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model25"},"description":"Successful"}}}},"/totp/exists":{"get":{"summary":"/totp/exists","operationId":"getTotpExists","description":"🔒 Authenticated with session token or password forgot token\n\nChecks to see if the user has a TOTP token.","tags":["totp"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model26"},"description":"Successful"}}}},"/account/device/commands":{"get":{"summary":"/account/device/commands","operationId":"getAccountDeviceCommands","description":"🔒 Authenticated with session token or authenticated with OAuth refresh token.\n\nFetches commands enqueued for the current device by prior calls to [/account/devices/invoke_command](#tag/Devices-and-Sessions/operation/postAccountDevicesInvoke_command). The device can page through the enqueued commands by using the `index` and `limit` parameters.\n\nFor more details, see the [device registration](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/docs/device_registration.md) docs.","parameters":[{"type":"number","description":"The index of the most recently seen command item. Only commands enqueued after the given index will be returned.","name":"index","in":"query","required":false},{"type":"number","description":"The maximum number of commands to return. The default and maximum value for limit is 100.","default":100,"minimum":0,"maximum":100,"name":"limit","in":"query","required":false}],"tags":["Devices and Sessions"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model28"},"description":"Successful"}}}},"/geo/eligibility/{feature}":{"get":{"summary":"geo/eligibility/{feature}","operationId":"getGeoEligibilityFeature","description":"🔒 Authenticated with session token\n\nReturns eligibility for a given feature based on user's country.","parameters":[{"type":"string","maxLength":64,"name":"feature","in":"path","required":true}],"tags":["Miscellaneous"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model29"},"description":"Successful"}}}},"/oauth/client/{client_id}":{"get":{"summary":"/oauth/client/{client_id}","operationId":"getOauthClientClient_id","description":"Retrieve metadata about the specified OAuth client, such as its display name and redirect URI.","parameters":[{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application) asking for permission.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16},"name":"client_id","in":"path","required":true}],"tags":["Oauth"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model30"},"description":"Successful"}}}},"/oauth/subscriptions/active":{"get":{"summary":"/oauth/subscriptions/active","operationId":"getOauthSubscriptionsActive","description":"🔒 Authenticated with OAuth bearer token\n\nReturns a list of active subscriptions for the user.","tags":["Subscriptions"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model32"},"description":"Successful"}}}},"/oauth/subscriptions/clients":{"get":{"summary":"/oauth/subscriptions/clients","operationId":"getOauthSubscriptionsClients","description":"🔒 [Authenticated with OAuth bearer token](https://github.com/mozilla/fxa/blob/95cded6e96e2b20f7593153a428d158001bb8d3b/packages/fxa-shared/oauth/constants.ts#L5)\n\nReturns a list of clients and their capabilities.","tags":["Subscriptions"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model34"},"description":"Successful"}}}},"/passkey/wraps/{credentialId}":{"get":{"summary":"/passkey/wraps/{credentialId}","operationId":"getPasskeyWrapsCredentialid","description":"🔒 Authenticated with MFA JWT (scope: mfa:passkey)\n\nReturns the wrap envelope for one passkey, as stored. Unsealing happens\nentirely on the client and needs the credential's WebAuthn PRF output, so\nthe envelope is inert to anyone who cannot complete an assertion with that\ncredential. The server never sees `kB`, the recipient private key, or the\nPRF output.\n\nThe token must be bound to `credentialId`, as it is for the write. A wrap\nis only ever fetched to complete a sign-in with that same credential.\n\nA wrap stored before the account's `keysChangedAt` seals a `kB` the\naccount no longer uses, and is withheld rather than returned — the client\nfalls back to a password sign-in and re-enrols.\n\n**Path parameters:**\n- `credentialId` (string, required) — base64url credential ID\n\n**Response:** the five base64url envelope fields (`pkR`,\n`prfWrappedSkR`, `keyWrapIv`, `hpkeEncapsulatedSecret`,\n`hpkeSealedKb`) plus `createdAt`.\n\n**Errors:**\n- `401` errno 223 — the token is invalid, or is not bound to `credentialId`\n- `404` errno 224 — no such passkey for this account\n- `404` errno 234 — the passkey has no wrap\n- `404` errno 236 — the wrap predates the account's `keysChangedAt`\n\n**Security events:** `account.passkey.wrap_retrieved` on a returned\nenvelope; `account.passkey.wrap_retrieval_failure` on an unbound token,\na stale wrap, or a lookup that finds none. Rejections before the handler\n— authentication and rate limiting — are not recorded. Both are recorded\nfor the audit trail and hidden from the account settings activity list.","parameters":[{"type":"string","maxLength":1364,"pattern":"^[A-Za-z0-9_-]+$","name":"credentialId","in":"path","required":true}],"tags":["Passkeys"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model35"},"description":"Successful"}}},"delete":{"summary":"/passkey/wraps/{credentialId}","operationId":"deletePasskeyWrapsCredentialid","description":"🔒 Authenticated with MFA JWT (scope: mfa:passkey)\n\nDeletes the wrap envelope for one passkey. The passkey itself stays\nregistered and usable. `POST /passkey/wraps` has no update path, so\ndeleting is how a client replaces an envelope it can no longer unseal:\ndelete, then post a fresh one built from a new assertion.\n\nThe token need not be bound to `credentialId`, unlike the read and the\nwrite — a delete is a management action, so settings can turn off\npasswordless sign-in for one passkey from any `mfa:passkey` token. Only\nthe authenticated account's own wraps are reachable.\n\nIdempotent: a credential that has no wrap answers `{ deleted: false }`\nrather than `404`. An unknown credential still `404`s — that is a\ndifferent account state, not a delete that already happened.\n\n**Path parameters:**\n- `credentialId` (string, required) — base64url credential ID\n\n**Response:** `{ deleted: boolean }` — false when the credential had\nno wrap to remove.\n\n**Errors:**\n- `401` errno 223 — the token is invalid\n- `404` errno 224 — no such passkey for this account\n\n**Security events:** `account.passkey.wrap_deleted` when a wrap was\nremoved, `account.passkey.wrap_deletion_failure` when the delete\nthrew. A credential that had no wrap is neither, having asked for a\nstate it is already in.","parameters":[{"type":"string","maxLength":1364,"pattern":"^[A-Za-z0-9_-]+$","name":"credentialId","in":"path","required":true}],"tags":["Passkeys"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model199"},"description":"Successful"}}}},"/oauth/subscriptions/iap/plans/{appName}":{"get":{"summary":"/oauth/subscriptions/iap/plans/{appName}","operationId":"getOauthSubscriptionsIapPlansAppname","description":"Returns available plans for In-App Purchase clients.","parameters":[{"type":"string","name":"appName","in":"path","required":true}],"tags":["Subscriptions"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/destroy":{"post":{"summary":"/v1/destroy","operationId":"postDestroy","description":"After a client is done using a token, the responsible thing to do is to destroy the token afterwards. A client can use this route to do so.\n\n**Request Parameters**\n- `token|access_token|refresh_token|refresh_token_id`: The hex string access token. By default, `token` is assumed to be the access token.","parameters":[{"type":"string","pattern":"^Basic\\s+([a-zA-Z0-9+=\\/]+)$","name":"authorization","in":"header","required":false},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model38"}}],"tags":["OAuth Server API Overview"],"responses":{"200":{"description":"A valid request will return an empty response, with a 200 status code.","schema":{"type":"string"}}},"x-codeSamples":[{"lang":"JavaScript","source":"curl -v \\\n -X POST \\\n -H \"Content-Type: application/json\" \\\n \"https://oauth.accounts.firefox.com/v1/destroy\" \\\n -d '{\n  \"token\": \"558f9980ad5a9c279beb52123653967342f702e84d3ab34c7f80427a6a37e2c0\"\n}'"}]}},"/get_random_bytes":{"post":{"summary":"/get_random_bytes","operationId":"postGet_random_bytes","description":"Get 32 bytes of random data. This should be combined with locally-sourced entropy when creating salts, etc.","tags":["Util"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/introspect":{"post":{"summary":"/v1/introspect","operationId":"postIntrospect","description":"This endpoint returns the status of the token and meta-information about this token.\n\nIf the token has attribute `active: false`, none of the other attributes in the response will have content.\n\nPer [RFC 9470](https://datatracker.ietf.org/doc/html/rfc9470) section 6.2, the response also\ncarries `acr`, `auth_time` and `amr` describing the authentication behind the grant.\nThese are present on **access tokens only** — a refresh token never carries them, which is what\nprevents an elevated authentication from surviving a token refresh. An RP that needs a fresh\nelevation must re-run the authorization flow rather than refreshing.\n\n**Units:** `auth_time` is in *seconds* since the epoch, following OIDC, while `iat` and\n`exp` on this endpoint are historically emitted in *milliseconds*. The difference is\nintentional and retained for backwards compatibility.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model39"}}],"tags":["OAuth Server API Overview"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model41"},"description":"A valid request will return a JSON response.\n<br />\n**Example:**\n``` js\n    {\n      \"active\": true,\n      \"scope\": \"profile https://identity.mozilla.com/account/subscriptions\",\n      \"client_id\": \"59cceb6f8c32317c\",\n      \"token_type\": \"access_token\",\n      \"iat\": 1566535888243,\n      \"sub\": \"913fe9395bb946b48c1521d7beb2cb24\",\n      \"jti\": \"5ae05d8fe413a749e0f4eb3c495a1c526fb52c85ca5fde516df5dd77d41f7b5b\",\n      \"exp\": 1566537688243,\n      \"acr\": \"AAL2\",\n      \"auth_time\": 1566535870,\n      \"amr\": [\"pwd\", \"otp\"]\n    }\n```"}},"x-codeSamples":[{"lang":"JavaScript","source":"curl -X POST \\\n -H \"Content-Type: application/json\" \\\n \"https://oauth.accounts.firefox.com/v1/introspect\" \\\n -d '{\n  \"token\": \"558f9980ad5a9c279beb52123653967342f702e84d3ab34c7f80427a6a37e2c0\"\n}'"}]}},"/newsletters":{"post":{"summary":"/newsletters","operationId":"postNewsletters","description":"🔒 Authenticated with OAuth bearer token or authenticated with session token","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model43"}}],"tags":["Miscellaneous"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/recoveryKey":{"post":{"summary":"/recoveryKey","operationId":"postRecoverykey","description":"🔒 Authenticated with session token\n\nCreates a new account recovery key for a user. Account recovery keys are one-time-use tokens that can be used to recover the user's kB if they forget their password. For more details, see the [account recovery keys](https://mozilla.github.io/ecosystem-platform/reference/tokens#account-recovery-tokens) docs.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model45"}}],"tags":["Account recovery key"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"delete":{"summary":"/recoveryKey","operationId":"deleteRecoverykey","description":"🔒 Authenticated with session token<br/><br/>This route remove an account's account recovery key. When the key is removed, it can no longer be used to restore an account's kB.","tags":["Account recovery key"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/token":{"post":{"summary":"/v1/token","operationId":"postToken","description":"After receiving an authorization grant from the user, clients exercise that grant at this endpoint to obtain tokens that can be used to access attached services for a particular user.\n\nThe following types of grant are possible:\n\n- `authorization_code`: a single-use code as produced by the [authorization][] endpoint, obtained through a redirect-based authorization flow.\n- `refresh_token`: a token previously obtained from this endpoint when using access_type=offline.\n- `fxa-credentials`: an FxA identity assertion, obtained by directly authenticating the user's account.\n\n**WARNING**: Do not include `scope` unless you want to downgrade it.\n\n**Step-up authentication.** An access token minted from an `authorization_code` grant carries\nthe `acr` and `auth_time` of the authentication behind that code. A `refresh_token`\ngrant carries neither: the refresh token stores no authentication event and the refresh grant\nnever re-evaluates `acr_values`/`max_age`, because no user is present to challenge. This is\ndeliberate — a client that needs a fresh elevation must re-run the authorization flow. Note\nthat a refreshed token still introspects as `active: true`, so a check that only reads\n`active` will not notice the elevation is gone.","parameters":[{"type":"string","pattern":"^Basic\\s+([a-zA-Z0-9+=\\/]+)$","name":"authorization","in":"header","required":false},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model46"}}],"tags":["OAuth Server API Overview"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model47"},"description":"A valid request will return a JSON response.\n<br />\n**Example:**\n``` js\n    {\n      \"access_token\": \"558f9980ad5a9c279beb52123653967342f702e84d3ab34c7f80427a6a37e2c0\",\n      \"scope\": \"profile:email profile:avatar\",\n      \"token_type\": \"bearer\",\n      \"expires_in\": 3600,\n      \"refresh_token\": \"58d59cc97c3ca183b3a87a65eec6f93d5be051415b53afbf8491cc4c45dbb0c6\",\n      \"auth_at\": 1422336613\n    }\n```"}},"x-codeSamples":[{"lang":"JavaScript","source":"curl -v \\\n -X POST \\\n -H \"Content-Type: application/json\" \\\n \"https://oauth.accounts.firefox.com/v1/token\" \\\n -d '{\n  \"client_id\": \"5901bd09376fadaa\",\n  \"client_secret\": \"20c6882ef864d75ad1587c38f9d733c80751d2cbc8614e30202dc3d1d25301ff\",\n  \"ttl\": 3600,\n  \"grant_type\": \"authorization_code\",\n  \"code\": \"4ab433e31ef3a7cf7c20590f047987922b5c9ceb1faff56f0f8164df053dd94c\"\n}'"}]}},"/verify":{"post":{"summary":"/v1/verify","operationId":"postVerify","description":"Attached services can post tokens to this endpoint to learn about which user and scopes are permitted for the token.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model48"}}],"tags":["OAuth Server API Overview"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model50"},"description":"A valid request will return a JSON response.\n\n- Note: `email` of the respective user has been **REMOVED**.\n\n**Example:**\n``` js\n    {\n      \"user\": \"5901bd09376fadaa076afacef5251b6a\",\n      \"client_id\": \"45defeda038a1c92\",\n      \"scope\": [\"profile:email\", \"profile:avatar\"],\n    }\n```"}},"x-codeSamples":[{"lang":"JavaScript","source":"curl -v \\\n -X POST \\\n -H \"Content-Type: application/json\" \\\n \"https://oauth.accounts.firefox.com/v1/verify\" \\\n -d '{\n  \"token\": \"558f9980ad5a9c279beb52123653967342f702e84d3ab34c7f80427a6a37e2c0\"\n}'"}]}},"/account/create":{"post":{"summary":"/account/create","operationId":"postAccountCreate","description":"Creates a user account. The client provides the email address with which this account will be associated and a stretched password. Stretching is detailed on the [onepw](https://mozilla.github.io/ecosystem-platform/explanation/onepw-protocol#client-side-key-stretching) wiki page.\n\nThis endpoint may send a verification email to the user. Callers may optionally provide the `service` parameter to indicate which service they are acting on behalf of. This is an opaque alphanumeric token that will be embedded in the verification link as a query parameter.\n\nCreating an account also logs in. The response contains a `sessionToken` and, optionally, a `keyFetchToken` if the url has a query parameter of `keys=true`.","parameters":[{"type":"boolean","description":"Indicates whether a key-fetch token should be returned in the success response.","name":"keys","in":"query","required":false},{"type":"string","description":"Opaque alphanumeric token to be included in verification links.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$","name":"service","in":"query"},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model51"}}],"tags":["Account"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model52"},"description":"Successful"},"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 101` - Account already exists\n- `errno: 144` - Email already exists"}}}},"/account/destroy":{"post":{"summary":"/account/destroy","operationId":"postAccountDestroy","description":"🔒🔓 Optionally authenticated with session token\n\nDeletes an account. All stored data is erased. The client should seek user confirmation first. The client should erase data stored on any attached services before deleting the user's account data.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model53"}}],"tags":["Account"],"responses":{"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 103` - Incorrect password\n- `errno: 138` - Unverified session"}}}},"/account/device":{"post":{"summary":"/account/device","operationId":"postAccountDevice","description":"🔒 Authenticated with session token or OAuth refresh token\n\nCreates or updates the [device registration](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/docs/device_registration.md) record associated with the auth token used for this request. At least one of `name`, `type`, `pushCallback` or the tuple `{ pushCallback, pushPublicKey, pushAuthKey }` must be present. Beware that if you provide `pushCallback` without the pair `{ pushPublicKey, pushAuthKey }`, both of those keys will be reset to the empty string.\n\n`pushEndpointExpired` will be reset to false on update if the tuple `{ pushCallback, pushPublicKey, pushAuthKey }` is specified.\n\nDevices should register with this endpoint before attempting to access the user's sync data, so that an appropriate device name can be made available to other connected devices.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model55"}}],"tags":["Devices and Sessions"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model56"},"description":"Successful"},"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 107` - Invalid parameter in request body"},"403":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 202` - Feature not enabled"}}}},"/account/email_bounce_status":{"post":{"summary":"/account/email_bounce_status","operationId":"postAccountEmail_bounce_status","description":"Checks if there are any hard (permanent) email bounces recorded for the provided email address. Used during signup confirmation to detect if verification emails are bouncing.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model57"}}],"tags":["Account"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model58"},"description":"Successful"}}}},"/account/login":{"post":{"summary":"/account/login","operationId":"postAccountLogin","description":"Obtain a `sessionToken` and, optionally, a `keyFetchToken` if `keys=true`.\n\nThe response includes:\n- `emailVerified`: Whether the account's primary email address has been verified\n- `sessionVerified`: Whether the current session token has been verified\n- `verified`: **Deprecated** - Whether both email and session are verified (equivalent to `emailVerified && sessionVerified`). Use `emailVerified` and `sessionVerified` instead.\n- `verificationMethod`: Present if verification is incomplete, e.g. `email`, `email-2fa`, `email-otp`, `totp-2fa`\n- `verificationReason`: Present if verification is incomplete, e.g. `login`, `signup`","parameters":[{"type":"boolean","description":"Indicates whether a key-fetch token should be returned in the success response.","name":"keys","in":"query","required":false},{"type":"string","description":"Opaque alphanumeric token to be included in verification links.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$","name":"service","in":"query"},{"type":"string","description":"If this param is specified, it forces the login to be verified using the specified method.\nCurrently supported methods:\n- `email`: Sends an email with a confirmation link.\n- `email-2fa`: Sends an email with a confirmation code.\n- `email-captcha`: Sends an email with an unblock code.","enum":["email","email-otp","email-2fa","email-captcha","totp-2fa"],"name":"verificationMethod","in":"query","required":false},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model59"}}],"tags":["Account"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model60"},"description":"Successful"},"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 102` - Unknown account\n- `errno: 103` - Incorrect password\n- `errno: 125` - The request was blocked for security reasons\n- `errno: 127` - Invalid unblock code\n- `errno: 142` - Sign in with this email type is not currently supported\n- `errno: 149` - This email can not currently be used to login\n- `errno: 160` - This request requires two step authentication enabled on your account"},"422":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 151` - Failed to send email"}}}},"/account/metrics_opt":{"post":{"summary":"/account/metrics_opt","operationId":"postAccountMetrics_opt","description":"Set the metrics opt-in or opt-out state for the account. Notifies relying parties of the profile data change.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model61"}}],"tags":["Account"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/account/reset":{"post":{"summary":"/account/reset","operationId":"postAccountReset","description":"🔒 Authenticated with account reset token\n\nThis sets the account password and resets `wrapKb` to a new random value.\n\nAccount reset tokens are single-use and consumed regardless of whether the request succeeds or fails. They are returned by the `POST /password/forgot/verify_code` endpoint.\n\nThe caller can optionally request a new `sessionToken` and `keyFetchToken`.","parameters":[{"type":"boolean","description":"Indicates whether a new `keyFetchToken` is required, default to `false`.","name":"keys","in":"query","required":false},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model62"}}],"tags":["Account"],"responses":{"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 108` - Missing parameter in request body"}}}},"/account/scoped-key-data":{"post":{"summary":"/account/scoped-key-data","operationId":"postAccountScopedkeydata","description":"🔒 Authenticated with session token\n\nQuery for the information required to derive scoped encryption keys requested by the specified OAuth client.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model63"}}],"tags":["Oauth"],"responses":{"200":{"schema":{"type":"object","properties":{"any":{"$ref":"#/definitions/any"}}},"description":"Successful"}}}},"/linked_account/login":{"post":{"summary":"/linked_account/login","operationId":"postLinked_accountLogin","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model66"}}],"tags":["Third Party Authentication"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model67"},"description":"Successful"}}}},"/linked_account/unlink":{"post":{"summary":"/linked_account/unlink","operationId":"postLinked_accountUnlink","description":"🔒 Authenticated with session token","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model68"}}],"tags":["Third Party Authentication"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model69"},"description":"Successful"}}}},"/mfa/recoveryCodes":{"post":{"summary":"/mfa/recoveryCodes","operationId":"postMfaRecoverycodes","description":"🔒 Authenticated with MFA jwt (scope: mfa:2fa)\n\nSet backup authentication codes (intended for initial set up)","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model10"}}],"tags":["Backup authentication codes"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model70"},"description":"Successful"}}},"put":{"summary":"/mfa/recoveryCodes","operationId":"putMfaRecoverycodes","description":"🔒 Authenticated with MFA jwt (scope: mfa:2fa)\n\nReturn new backup authentication codes while removing old ones.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model10"}}],"tags":["Backup authentication codes"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model197"},"description":"Successful"}}}},"/mfa/recoveryKey":{"post":{"summary":"/recoveryKey","operationId":"postMfaRecoverykey","description":"🔒 Authenticated with MFA jwt\n\nCreates a new account recovery key for a user. Account recovery keys are one-time-use tokens that can be used to recover the user's kB if they forget their password. For more details, see the [account recovery keys](https://mozilla.github.io/ecosystem-platform/reference/tokens#account-recovery-tokens) docs.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model71"}}],"tags":["Account recovery key"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}},"delete":{"summary":"/recoveryKey","operationId":"deleteMfaRecoverykey","description":"🔒 Authenticated with MFA JWT (scope: mfa:recovery_key)<br/><br/>This route remove an account's account recovery key. When the key is removed, it can no longer be used to restore an account's kB.","tags":["Account recovery key"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/mfa/recovery_email":{"post":{"summary":"/recovery_email","operationId":"postMfaRecovery_email","description":"🔒 Authenticated with MFA JWT (scope: mfa:email)\nAdd a secondary email address to the logged-in account. The created address will be unverified and will not replace the primary email address.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model72"}}],"tags":["Emails"],"responses":{"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 104` - Unverified account\n- `errno: 138` - Unverified session\n- `errno: 139` - Can not add secondary email that is same as your primary\n- `errno: 140` - Email already exists\n- `errno: 141` - Email already exists"}}}},"/oauth/authorization":{"post":{"summary":"/oauth/authorization","operationId":"postOauthAuthorization","description":"🔒 Authenticated with session token\n\nAuthorize a new OAuth client connection to the user's account, returning a short-lived authentication code that the client can exchange for access tokens at the OAuth token endpoint.\n\nThis route behaves like the oauth-server /authorization endpoint except that it is authenticated directly with a sessionToken.\n\n### Step-up authentication (RFC 9470)\n\nAn RP can request a higher authentication level with `acr_values=AAL2`, and can bound its freshness with `max_age`. The two are independent and each is optional; a session failing either one is rejected here with `errno: 170`.\n\nThe hosted sign-in UI resolves that with a second-factor challenge. Where it cannot — the RP sent `prompt=none` — it redirects to the registered `redirect_uri` with `error=unmet_authentication_requirements` instead. That redirect comes from the UI, never from this endpoint.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model74"}}],"tags":["Oauth"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model75"},"description":"Successful"},"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 170` - Requested `acr_values` or `max_age` could not be satisfied."}}}},"/oauth/destroy":{"post":{"summary":"/oauth/destroy","operationId":"postOauthDestroy","description":"Destroy an OAuth access token or refresh token.\n\nThis is the \"token revocation endpoint\" as defined in RFC7009 and should be used by clients to explicitly revoke any OAuth tokens that they are no longer using.\n\nOne of either an authorization header or a client_id is required.","parameters":[{"type":"string","pattern":"^Basic\\s+([a-zA-Z0-9+=\\/]+)$","name":"authorization","in":"header","required":false},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model76"}}],"tags":["Oauth"],"responses":{"200":{"description":"No information is returned in the response body.","schema":{"type":"string"}},"401":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 171` - Incorrect client secret"},"500":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 162` - Unknown client id."}}}},"/oauth/id-token-verify":{"post":{"summary":"/oauth/id-token-verify","operationId":"postOauthIdtokenverify","description":"Verifies an OIDC ID Token (FxA returns this token at the end of the OAuth flow). The id token contains the user's identification number (uid) plus [other fields](https://openid.net/specs/openid-connect-core-1_0.html#IDToken).","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model77"}}],"tags":["Miscellaneous"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model79"},"description":"Successful"}}}},"/oauth/token":{"post":{"summary":"/oauth/token","operationId":"postOauthToken","description":"🔒🔓 Optionally authenticated with session token\n\nGrant new OAuth tokens for use by a connected client, using one of the following grant types:\n  - `grant_type=authorization_code`: A single-use code obtained via OAuth redirect flow.\n  - `grant_type=refresh_token`: A refresh token issued by a previous call to this endpoint.\n  - `grant_type=fxa-credentials`: Directly grant tokens using an FxA sessionToken.\n\nThis is the \"token endpoint\" as defined in RFC6749, and behaves like the [oauth-server /token endpoint](#tag/OAuth-Server-API-Overview/operation/postToken) except that the `fxa-credentials` grant can be authenticated directly with a sessionToken.","parameters":[{"x-alternatives":[{"$ref":"#/x-alt-definitions/Model1"},{"$ref":"#/x-alt-definitions/Model3"},{"$ref":"#/x-alt-definitions/Model5"},{"$ref":"#/x-alt-definitions/Model7"}],"in":"body","name":"body","schema":{"$ref":"#/definitions/Model81"}}],"tags":["Oauth"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model82","x-alternatives":[{"$ref":"#/x-alt-definitions/Model8"},{"$ref":"#/x-alt-definitions/Model10"},{"$ref":"#/x-alt-definitions/Model12"},{"$ref":"#/x-alt-definitions/Model14"}]},"description":"Successful"},"401":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 110` - Invalid authentication token in request signature"},"500":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 998` - An internal validation check failed"}}}},"/passkey/wraps":{"post":{"summary":"/passkey/wraps","operationId":"postPasskeyWraps","description":"🔒 Authenticated with MFA JWT (scope: mfa:passkey)\n\nStores the wrap envelope for one passkey. The envelope is produced entirely\non the client: `kB` is sealed with HPKE to a per-wrap recipient key, whose\nprivate half is encrypted under a key derived from the credential's WebAuthn\nPRF output. The server stores all five fields uninterpreted and never sees\n`kB`, the private key, or the PRF output.\n\nThe token must be bound to `credentialId`, which `/passkey/authentication/finish`\ndoes when `/start` asks for the `passkey` scope. A token minted any other way\ncarries no binding and is rejected.\n\n**Request body:**\n- `credentialId` (string, required) — base64url credential ID\n- `pkR` (string, required) — base64url, 133 bytes\n- `prfWrappedSkR` (string, required) — base64url, 82 bytes\n- `keyWrapIv` (string, required) — base64url, 12 bytes\n- `hpkeEncapsulatedSecret` (string, required) — base64url, 133 bytes\n- `hpkeSealedKb` (string, required) — base64url, 48 bytes\n\n**Response:** `{ created: boolean }` — false when an identical wrap was\nalready stored. A different wrap that predates the account's\n`keysChangedAt` seals a `kB` the account no longer has and is replaced.\n\n**Errors:**\n- `401` errno 223 — the token is invalid, or is not bound to `credentialId`\n- `404` errno 224 — the passkey was deleted after the assertion\n- `409` errno 235 — a different wrap from the current key epoch already exists for this credential\n\n**Security events:** `account.passkey.wrap_created` on a new wrap;\n`account.passkey.wrap_creation_failure` on any failure to store one.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model83"}}],"tags":["Passkeys"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model84"},"description":"Successful"}}}},"/password/create":{"post":{"summary":"/password/create","operationId":"postPasswordCreate","description":"🔒 Authenticated with session token\n\nCreates a new password for the user associated with the session token. Creating a new password will generate new encryption key.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model85"}}],"tags":["Password"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/recoveryKey/exists":{"post":{"summary":"/recoveryKey/exists","operationId":"postRecoverykeyExists","description":"🔒🔓 Authenticated with session token or password-forgot token<br/><br/>This route checks to see if given user has setup an account recovery key. When used during the password reset flow, a password-forgot token to check for the status.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model86"}}],"tags":["Account recovery key"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model87"},"description":"Successful"}}}},"/recoveryKey/hint":{"post":{"summary":"/recoveryKey/hint","operationId":"postRecoverykeyHint","description":"🔒 Authenticated with session token<br/><br/>This route updates the hint associated with a userʼs recovery key.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model88"}}],"tags":["Account recovery key"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/recoveryKey/verify":{"post":{"summary":"/recoveryKey/verify","operationId":"postRecoverykeyVerify","description":"🔒 Authenticated with session token","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model89"}}],"tags":["Account recovery key"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/recovery_email/resend_code":{"post":{"summary":"/recovery_email/resend_code","operationId":"postRecovery_emailResend_code","description":"🔒 Authenticated with session token\n\nRe-sends a verification code to the account's recovery email address. The code is first sent when the account is created, but if the user thinks the message was lost or accidentally deleted, they can request a new message to be sent via this endpoint. The new message will contain the same code as the original message. When this code is provided to `/v1/recovery_email/verify_code`, the email will be marked as 'verified'.\n\nThis endpoint may send a verification email to the user. Callers may optionally provide the `service` parameter to indicate what identity-attached service they're acting on behalf of. This is an opaque alphanumeric token that will be embedded in the verification link as a query parameter.","parameters":[{"type":"string","description":"Opaque alphanumeric token to be included in verification links.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$","name":"service","in":"query"},{"type":"string","enum":["upgradeSession"],"maxLength":32,"x-format":{"alphanum":true},"name":"type","in":"query","required":false},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model90"}}],"tags":["Emails"],"responses":{"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 150` - Can not resend email code to an email that does not belong to this account"}}}},"/recovery_email/verify_code":{"post":{"summary":"/recovery_email/verify_code","operationId":"postRecovery_emailVerify_code","description":"Verify tokens and/or recovery emails for an account. If a valid token code is detected, the account email and tokens will be set to verified. If a valid email code is detected, the email will be marked as verified.\n\nThe verification code will be a random token, delivered in the fragment identifier of a URL sent to the user's email address. Navigating to the URL opens a page that extracts the code from the fragment identifier and performs a POST to `/recovery_email/verify_code`. The link can be clicked from any browser, not just the one being attached to the Firefox account.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model93"}}],"tags":["Emails"],"responses":{"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 105` - Invalid verification code"}}}},"/recovery_phone/available":{"post":{"summary":"/recovery_phone/available","operationId":"postRecovery_phoneAvailable","description":"🔒 Authenticated with session token\n\nReturns whether the user can set up a recovery phone in their current region and account state.","tags":["Recovery phone"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/recovery_phone/confirm":{"post":{"summary":"/recovery_phone/confirm","operationId":"postRecovery_phoneConfirm","description":"🔒 Authenticated with verified session token\n\nConfirm recovery phone setup by verifying the code sent via SMS and finalize adding the phone number.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model94"}}],"tags":["Recovery phone"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/recovery_phone/create":{"post":{"summary":"/recovery_phone/create","operationId":"postRecovery_phoneCreate","description":"🔒 Authenticated with verified session token\n\nStart recovery phone setup by validating and sending a verification code to the provided number.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model95"}}],"tags":["Recovery phone"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/recovery_phone/message_status":{"post":{"summary":"/recovery_phone/message_status","operationId":"postRecovery_phoneMessage_status","description":"Public webhook (Twilio)\n\nAccept message status callbacks from Twilio. The request is validated using either an FxA-generated signature or Twilio's signature.","tags":["Recovery phone"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/session/destroy":{"post":{"summary":"/session/destroy","operationId":"postSessionDestroy","description":"🔒 Authenticated with session token\n\nDestroys the current session and invalidates `sessionToken`, to be called when a user signs out. To sign back in, a call must be made to `POST /account/login` to obtain a new `sessionToken`.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model96"}}],"tags":["Session"],"responses":{"401":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 110` - Invalid authentication token in request signature"}}}},"/session/duplicate":{"post":{"summary":"/session/duplicate","operationId":"postSessionDuplicate","description":"🔒 Authenticated with session token\n\nCreate a new `sessionToken` that duplicates the current session. It will have the same verification status as the current session, but will have a distinct verification code.\n\n**Response object:**\n- `uid`: Account id\n- `sessionToken`: Session Token\n- `authAt`: Authentication timestamp\n- `emailVerified`: Whether the account's primary email is verified\n- `sessionVerified`: Whether the session token itself is verified (no pending token verification)\n- `verificationMethod`: Present if verification is incomplete, e.g. `email`, `email-2fa`, `email-otp`, `totp-2fa`\n- `verificationReason`: Present if verification is incomplete, e.g. `login`, `signup`\n- `verified`: Deprecated! Use emailVerified and sessionVerified instead.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model97"}}],"tags":["Session"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model98"},"description":"Successful"}}}},"/session/reauth":{"post":{"summary":"/session/reauth","operationId":"postSessionReauth","description":"🔒 Authenticated with session token\n\nRe-authenticate an existing session token. This is equivalent to calling `/account/login`, but it re-uses an existing session token rather than generating a new one, allowing the caller to maintain session state such as verification and device registration.\n\nThe response includes:\n- `uid`: Account id\n- `keyFetchToken`: Present if keys were requested.\n- `verificationMethod`: Present if verification is incomplete, e.g. `email`, `email-2fa`, `email-otp`, `totp-2fa`\n- `verificationReason`: Present if verification is incomplete, e.g. `login`, `signup`\n- `emailVerified`: Whether the account's primary email address has been verified\n- `sessionVerified`: Whether the current session token has been verified\n- `authAt`: Timestamp of authentication\n- `metricsEnabled`: Flag indicating if metrics are enabled on the session\n- `verified`: Deprecated! Use emailVerified and sessionVerified instead.","parameters":[{"type":"boolean","name":"keys","in":"query","required":false},{"type":"string","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$","name":"service","in":"query"},{"type":"string","enum":["email","email-otp","email-2fa","email-captcha","totp-2fa"],"name":"verificationMethod","in":"query","required":false},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model100"}}],"tags":["Session"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model101"},"description":"Successful"},"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 102` - Unknown account\n- `errno: 103` - Incorrect password\n- `errno: 125` - The request was blocked for security reasons\n- `errno: 127` - Invalid unblock code\n- `errno: 142` - Sign in with this email type is not currently supported\n- `errno: 149` - This email can not currently be used to login\n- `errno: 160` - This request requires two-step authentication enabled on your account"}}}},"/session/resend_code":{"post":{"summary":"/session/resend_code","operationId":"postSessionResend_code","description":"🔒 Authenticated with session token","tags":["Session"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/session/verify_code":{"post":{"summary":"/session/verify_code","operationId":"postSessionVerify_code","description":"🔒 Authenticated with session token","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model104"}}],"tags":["Session"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/support/ticket":{"post":{"summary":"/support/ticket","operationId":"postSupportTicket","description":"🔒 Authenticated with support secret or authenticated with OAuth bearer token\n\nCreates a support ticket using the Zendesk client.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model105"}}],"tags":["Miscellaneous"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model106"},"description":"Successful"}}}},"/totp/verify":{"post":{"summary":"/totp/verify","operationId":"postTotpVerify","description":"🔒 Authenticated with password forgot token\n\nChecks to see if a TOTP code is valid. This is used when a user is resetting their password.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model107"}}],"tags":["totp"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model108"},"description":"Successful"}}}},"/account/attached_client/destroy":{"post":{"summary":"/account/attached_client/destroy","operationId":"postAccountAttached_clientDestroy","description":"🔒 Authenticated with session token\n\nDestroy all tokens held by a connected client, disconnecting it from the user's account.\n\nThis endpoint is designed to be used in conjunction with [/account/attached_clients](#tag/Devices-and-Sessions/operation/getAccountAttached_clients). It accepts as the request body an object in the same format as returned by that endpoing, and will disconnect that client from the user's account.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model109"}}],"tags":["Devices and Sessions"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model110"},"description":"Successful"}}}},"/account/credentials/status":{"post":{"summary":"/account/credentials/status","operationId":"postAccountCredentialsStatus","description":"This provides access to the accounts some info about the format of the account credentials. If the version 2 credential\nformat is in use, the client's unique salt will also be provided.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model111"}}],"tags":["Account"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model112"},"description":"Successful"},"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 108` - Missing parameter in request body"}}}},"/account/device/destroy":{"post":{"summary":"/account/device/destroy","operationId":"postAccountDeviceDestroy","description":"🔒 Authenticated with session token or authenticated with OAuth refresh token\n\nDestroys a device record and the associated `sessionToken` for the authenticated user.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model113"}}],"tags":["Devices and Sessions"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model114"},"description":"Successful"}}}},"/account/devices/invoke_command":{"post":{"summary":"/account/devices/invoke_command","operationId":"postAccountDevicesInvoke_command","description":"🔒 Authenticated with session token or authenticated with OAuth refresh token.\n\nEnqueues a command to be invoked on a target device.\n\nFor more details, see the [device registration](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/docs/device_registration.md) docs.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model116"}}],"tags":["Devices and Sessions"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model117"},"description":"Successful"},"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 157` - Unavailable device command"}}}},"/account/devices/notify":{"post":{"summary":"/account/devices/notify","operationId":"postAccountDevicesNotify","description":"🔒 Authenticated with session token or authenticated with OAuth refresh token.\n\nNotifies a set of devices associated with the user's account of an event by sending a browser push notification. A typical use case would be to send a notification to another device after sending a tab with Sync, so it can sync too and display the tab in a timely manner.","parameters":[{"x-alternatives":[{"$ref":"#/x-alt-definitions/Model15"},{"$ref":"#/x-alt-definitions/Model18"}],"in":"body","name":"body","schema":{"$ref":"#/definitions/Model119"}}],"tags":["Devices and Sessions"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model120"},"description":"Successful"},"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 107` - Invalid parameter in request body"},"403":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 202` - Feature not enabled"}}}},"/account/login/reject_unblock_code":{"post":{"summary":"/account/login/reject_unblock_code","operationId":"postAccountLoginReject_unblock_code","description":"Used to reject and report unblock codes that were not requested by the user.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model121"}}],"tags":["Unblock codes"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/account/login/send_unblock_code":{"post":{"summary":"/account/login/send_unblock_code","operationId":"postAccountLoginSend_unblock_code","description":"Send an unblock code via email to reset rate-limiting for an account.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model122"}}],"tags":["Unblock codes"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/account/passwordless/confirm_code":{"post":{"summary":"/account/passwordless/confirm_code","operationId":"postAccountPasswordlessConfirm_code","description":"Confirm the OTP code sent via `/account/passwordless/send_code`.\n\nOn success:\n- For new users: Creates a new account and returns a session token\n- For existing users: Returns a session token for the existing account\n\nThe `isNewAccount` field in the response indicates whether a new account was created.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model123"}}],"tags":["Passwordless"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model125"},"description":"Successful"},"400":{"description":"Failing requests may be caused by the following errors:\n- `errno: 183` - Invalid OTP code\n- `errno: 148` - Account has a password set"},"429":{"description":"Rate limit exceeded"}}}},"/account/passwordless/resend_code":{"post":{"summary":"/account/passwordless/resend_code","operationId":"postAccountPasswordlessResend_code","description":"Resend the OTP code for passwordless authentication.\n\nThis invalidates any previously sent code and sends a new one.\nSubject to the same rate limits as `/account/passwordless/send_code`.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model126"}}],"tags":["Passwordless"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model127"},"description":"Successful"},"400":{"description":"Failing requests may be caused by the following errors:\n- `errno: 148` - Account has a password set"},"429":{"description":"Rate limit exceeded"}}}},"/account/passwordless/send_code":{"post":{"summary":"/account/passwordless/send_code","operationId":"postAccountPasswordlessSend_code","description":"Send a one-time password (OTP) code to the user's email for passwordless authentication.\n\nThis endpoint can be used for both:\n- New user registration (account doesn't exist)\n- Login for existing passwordless accounts (accounts without a password)\n\nAccounts with passwords set cannot use this endpoint.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model128"}}],"tags":["Passwordless"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model129"},"description":"Successful"},"400":{"description":"Failing requests may be caused by the following errors:\n- `errno: 148` - Account has a password set, use standard login flow"},"429":{"description":"Rate limit exceeded"}}}},"/emails/reminders/cad":{"post":{"summary":"/emails/reminders/cad","operationId":"postEmailsRemindersCad","description":"🔒 Authenticated with session token","tags":["Emails"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/mfa/password/change":{"post":{"summary":"/mfa/password/change","operationId":"postMfaPasswordChange","description":"🔒 Authenticated with MFA JWT (scope: mfa:password)\n\nPerform the \"change password\" process using JWT authentication. Returns a session token and a key fetch token.","parameters":[{"type":"boolean","description":"Indicates whether a new `keyFetchToken` is required, default to `false`.","name":"keys","in":"query","required":false},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model130"}}],"tags":["Password"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/mfa/password/create":{"post":{"summary":"/mfa/password/create","operationId":"postMfaPasswordCreate","description":"🔒 Authenticated with MFA JWT (scope: mfa:password)\n\nCreates a new password for the user associated with the session token. Creating a new password will generate new encryption key.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model131"}}],"tags":["Password"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/mfa/recovery_email/destroy":{"post":{"summary":"/mfa/recovery_email/destroy","operationId":"postMfaRecovery_emailDestroy","description":"🔒 Authenticated with session MFA JWT (scope: mfa:email)\n\nDelete an email address associated with the logged-in user.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model132"}}],"tags":["Emails"],"responses":{"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 138` - Unverified session"},"401":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 110` - Invalid authentication token in request signature"}}}},"/mfa/recovery_email/set_primary":{"post":{"summary":"/mfa/recovery_email/set_primary","operationId":"postMfaRecovery_emailSet_primary","description":"🔒 Authenticated with session MFA JWT (scope: mfa:email)\n\nThis endpoint changes a user's primary email address. This email address must belong to the user and be verified.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model133"}}],"tags":["Emails"],"responses":{"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 138` - Unverified session\n- `errno: 147` - Can not change primary email to an unverified email\n- `errno: 148` - Can not change primary email to an email that does not belong to this account"},"401":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 110` - Invalid authentication token in request signature"}}}},"/mfa/recovery_phone/change":{"post":{"summary":"/mfa/recovery_phone/change","operationId":"postMfaRecovery_phoneChange","description":"🔒 Authenticated with MFA JWT (scope: mfa:2fa)\nReplace the existing recovery phone with a new one using a valid setup code for the new number.","tags":["Recovery phone"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/mfa/recovery_phone/confirm":{"post":{"summary":"/mfa/recovery_phone/confirm","operationId":"postMfaRecovery_phoneConfirm","description":"🔒 Authenticated with MFA JWT (scope: mfa:2fa)\n\nConfirm recovery phone setup (MFA JWT variant) by verifying the code sent via SMS and finalize adding the phone number.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model134"}}],"tags":["Recovery phone"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/mfa/recovery_phone/create":{"post":{"summary":"/mfa/recovery_phone/create","operationId":"postMfaRecovery_phoneCreate","description":"🔒 Authenticated with MFA JWT (scope: mfa:2fa)\n\nStart recovery phone setup (MFA JWT variant) by validating and sending a verification code to the provided number.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model135"}}],"tags":["Recovery phone"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/mfa/totp/create":{"post":{"summary":"/mfa/totp/create","operationId":"postMfaTotpCreate","description":"🔒 Authenticated with MFA JWT (scope: mfa:2fa)\n\nCreate a new randomly generated TOTP token for a user if they do not currently have one. This variant requires an MFA JWT and is intended for flows that have already passed MFA requirements.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model136"}}],"tags":["totp"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model137"},"description":"Successful"}}}},"/mfa/totp/destroy":{"post":{"summary":"/mfa/totp/destroy","operationId":"postMfaTotpDestroy","description":"🔒 Authenticated with MFA JWT (scope: mfa:2fa)\n\nDeletes the current TOTP token for the user. The underlying session needs to have been verified by TOTP to remove it. It does not bypass that requirement.","tags":["totp"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/passkey/authentication/finish":{"post":{"summary":"/passkey/authentication/finish","operationId":"postPasskeyAuthenticationFinish","description":"🔓 Unauthenticated\n\nCompletes the WebAuthn authentication ceremony. On success, returns an\nAAL2 session token.\n\n**Request body:**\n- `response` (object, required) — AuthenticationResponseJSON from the browser\n- `challenge` (string, required) — challenge from the start endpoint\n- `service` (string, optional) — OAuth service identifier (e.g. `\"sync\"`)\n- `keysRequired` (boolean, required) — when `true`, this login still needs\n  Sync-scoped keys obtained via a follow-up step (a password step today), so\n  the server defers its login notifications/metrics until keys are available.\n\n**Response:** `uid`, `sessionToken`, `verified`, `hasPassword`, and\n`mfaToken` when `/start` was given a `scope`. The token carries that scope\nand the credential that signed the assertion.\n\n**Security event:** `account.passkey.authentication_success` recorded on success.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model140"}}],"tags":["Passkeys"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model141"},"description":"Successful"}}}},"/passkey/authentication/start":{"post":{"summary":"/passkey/authentication/start","operationId":"postPasskeyAuthenticationStart","description":"🔓 Unauthenticated\n\nInitiates the WebAuthn authentication ceremony. Returns\n`PublicKeyCredentialRequestOptionsJSON` to pass to\n`navigator.credentials.get`. `allowCredentials` is always empty\n`allowCredentials` is omitted when the allow-list is empty (discoverable flow).\n\n**Request body:**\n- `keysRequired` (boolean, optional) — hint for the keys-required PRF scope\n- `scope` (string, optional) — an MFA action from `config.mfa.actions`. Stored\n  on the challenge, so `/finish` returns an `mfa:<scope>` token for it.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model143"}}],"tags":["Passkeys"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model146"},"description":"Successful"}}}},"/passkey/registration/finish":{"post":{"summary":"/passkey/registration/finish","operationId":"postPasskeyRegistrationFinish","description":"🔒 Authenticated with MFA JWT (scope: mfa:passkey)\n\nCompletes the WebAuthn registration ceremony by verifying the attestation\nresponse from the authenticator. On success, stores the new passkey credential\nand returns its metadata.\n\n**Request body:**\n- `response` (object, required) — RegistrationResponseJSON from the browser\n- `challenge` (string, required) — The challenge returned by the start endpoint\n\n**Response:** passkey metadata, the same shape `GET /passkeys` returns.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model150"}}],"tags":["Passkeys"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model4"},"description":"Successful"}}}},"/passkey/registration/start":{"post":{"summary":"/passkey/registration/start","operationId":"postPasskeyRegistrationStart","description":"🔒 Authenticated with MFA JWT (scope: mfa:passkey)\n\nInitiates the WebAuthn registration ceremony by generating a challenge and\nregistration options for the authenticator. The returned options should be\npassed to the WebAuthn client-side API (navigator.credentials.create).\n\n**Request body:** none\n\n**Response:** PublicKeyCredentialCreationOptionsJSON — pass directly to\n`navigator.credentials.create({ publicKey: response })`.","tags":["Passkeys"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model160"},"description":"Successful"}}}},"/passkey/verification/finish":{"post":{"summary":"/passkey/verification/finish","operationId":"postPasskeyVerificationFinish","description":"🔒 Authenticated with session token (verified)\n\nCompletes the MFA step-up ceremony. No session token is created: the\ncaller already has one.\n\n**Request body:**\n- `response` (object, required) - AuthenticationResponseJSON from the browser\n- `challenge` (string, required) - challenge from the start endpoint\n\n**Response:** `mfaToken`, whose claims carry the scope the challenge\nwas created with (`mfa:<scope>`), the caller's session (`stid`), and\nthe credential that signed the assertion (`cid`).\n\n**Security events:** `account.passkey.verification_success` or\n`account.passkey.verification_failure`.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model163"}}],"tags":["Passkeys"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model164"},"description":"Successful"}}}},"/passkey/verification/start":{"post":{"summary":"/passkey/verification/start","operationId":"postPasskeyVerificationStart","description":"🔒 Authenticated with session token (verified)\n\nInitiates an MFA step-up for the caller's session. Returns\n`PublicKeyCredentialRequestOptionsJSON` to pass to\n`navigator.credentials.get`. `allowCredentials` lists the account's\npasskeys, or just the pinned one. PRF is never requested: this ceremony\nonly proves the user is present with a registered passkey.\n\n**Request body:**\n- `scope` (string, required) - an MFA action from `config.mfa.actions`.\n  Stored on the challenge, so `/finish` mints an `mfa:<scope>` token for it.\n- `credentialId` (string, optional) - pins the ceremony to one of the\n  account's passkeys.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model166"}}],"tags":["Passkeys"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model169"},"description":"Successful"}}}},"/password/change/finish":{"post":{"summary":"/password/change/finish","operationId":"postPasswordChangeFinish","description":"🔒 Authenticated with password change token\n\nChange the password and update `wrapKb`. Optionally returns `sessionToken` and `keyFetchToken`.","parameters":[{"type":"boolean","description":"Indicates whether a new `keyFetchToken` is required, default to `false`.","name":"keys","in":"query","required":false},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model170"}}],"tags":["Password"],"responses":{"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 138` - Unverified session"}}}},"/password/change/start":{"post":{"summary":"/password/change/start","operationId":"postPasswordChangeStart","description":"Begin the \"change password\" process. Returns a single-use `passwordChangeToken`, to be sent to `POST /password/change/finish`. Also returns a single-use `keyFetchToken`.<br/><br/>Important! the email value must be the original account email, i.e. the email used during initial sign up, and NOT the current primary email!","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model171"}}],"tags":["Password"],"responses":{"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 103` - Incorrect password"}}}},"/password/forgot/send_otp":{"post":{"summary":"/password/forgot/send_otp","operationId":"postPasswordForgotSend_otp","description":"Requests a One-time Password to be sent to the account's email address(es).  The OTP will need to be POSTed to `/password/forgot/verify_otp` to continue the reset password process.","parameters":[{"type":"string","description":"Identifies the relying service the user was interacting with that triggered the password reset.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$","name":"service","in":"query"},{"type":"boolean","name":"keys","in":"query","required":false},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model172"}}],"tags":["Password"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/password/forgot/verify_code":{"post":{"summary":"/password/forgot/verify_code","operationId":"postPasswordForgotVerify_code","description":"🔒 Authenticated with password forgot token\n\nThe code returned by `POST /v1/password/forgot/send_code` should be submitted to this endpoint with the `passwordForgotToken`. For successful requests, the server will return `accountResetToken`, to be submitted in requests to `POST /account/reset` to reset the account password and `wrapKb`.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model173"}}],"tags":["Password"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model174"},"description":"Successful"},"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 105` - Invalid verification code"}}}},"/password/forgot/verify_otp":{"post":{"summary":"/password/forgot/verify_otp","operationId":"postPasswordForgotVerify_otp","description":"Verify the OTP from `/password/forgot/send_otp` to receive the PasswordForgotToken and its code to continue the password reset process.\n\nWhen the passkey feature is enabled, the response also carries `hasPasskey` (the account has a registered passkey) and `hasPasskeyWraps` (a passkey can recover the account's encryption keys without the password). Both drive the reset-flow messaging and are omitted when the lookup fails. They are exposed here — behind the verified OTP — and not on `/account/status`.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model175"}}],"tags":["Password"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model176"},"description":"Successful"}}}},"/recovery_phone/reset_password/confirm":{"post":{"summary":"/recovery_phone/reset_password/confirm","operationId":"postRecovery_phoneReset_passwordConfirm","description":"🔒 Authenticated with password forgot token\n\nVerify the SMS code sent to the recovery phone to complete password reset verification.","tags":["Recovery phone"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/recovery_phone/reset_password/send_code":{"post":{"summary":"/recovery_phone/reset_password/send_code","operationId":"postRecovery_phoneReset_passwordSend_code","description":"🔒 Authenticated with password forgot token\n\nSend an SMS code to the configured recovery phone to confirm a password reset.","tags":["Recovery phone"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/recovery_phone/signin/confirm":{"post":{"summary":"/recovery_phone/signin/confirm","operationId":"postRecovery_phoneSigninConfirm","description":"🔒 Authenticated with session token\n\nVerify the SMS code sent to the recovery phone to complete sign-in.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model177"}}],"tags":["Recovery phone"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/recovery_phone/signin/send_code":{"post":{"summary":"/recovery_phone/signin/send_code","operationId":"postRecovery_phoneSigninSend_code","description":"🔒 Authenticated with session token\n\nSend an SMS code to the configured recovery phone to complete sign-in as a 2-step verification method.","tags":["Recovery phone"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/session/verify/totp":{"post":{"summary":"/session/verify/totp","operationId":"postSessionVerifyTotp","description":"🔒 Authenticated with session token\n\nVerifies the current session if the passed TOTP code is valid.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model178"}}],"tags":["totp"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model179"},"description":"Successful"}}}},"/totp/verify/recoveryCode":{"post":{"summary":"/totp/verify/recoveryCode","operationId":"postTotpVerifyRecoverycode","description":"🔒 Authenticated with password forgot token\n\nChecks to see if a Recovery code is valid. If the code is valid, it will be consumed and deleted. This is used when a user is resetting their password.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model180"}}],"tags":["totp"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model181"},"description":"Successful"}}}},"/mfa/recovery_email/secondary/resend_code":{"post":{"summary":"/recovery_email/secondary/resend_code","operationId":"postMfaRecovery_emailSecondaryResend_code","description":"🔒 Authenticated with session token\n\nThis endpoint resend the otp verification to verify the secondary email.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model182"}}],"tags":["Emails"],"responses":{"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 138` - Unverified session\n- `errno: 150` - Can not resend email code to an email that does not belong to this account"}}}},"/mfa/recovery_email/secondary/verify_code":{"post":{"summary":"/recovery_email/secondary/verify_code","operationId":"postMfaRecovery_emailSecondaryVerify_code","description":"🔒 Authenticated with session MFA JWT (scope: mfa:email)\n\nThis endpoint verifies a secondary email using a time based (otp) code.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model183"}}],"tags":["Emails"],"responses":{"400":{"description":"Failing requests may be caused by the following errors (this is not an exhaustive list):\n- `errno: 138` - Unverified session\n- `errno: 105` - Invalid verification code"}}}},"/mfa/totp/replace/confirm":{"post":{"summary":"/mfa/totp/replace/confirm","operationId":"postMfaTotpReplaceConfirm","description":"🔒 Authenticated with MFA JWT (scope: mfa:2fa)\n\nVerifies the provided code is valid for TOTP and sets the new TOTP token for the user. This is used when a user is replacing their existing TOTP token.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model184"}}],"tags":["totp"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model185"},"description":"Successful"}}}},"/mfa/totp/replace/start":{"post":{"summary":"/mfa/totp/replace/start","operationId":"postMfaTotpReplaceStart","description":"🔒 Authenticated with MFA JWT (scope: mfa:2fa)\n\nCreate a new randomly generated TOTP token for a user to replace an existing one. An existing TOTP token must exist for the user to request a replacement.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model186"}}],"tags":["totp"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model187"},"description":"Successful"}}}},"/mfa/totp/setup/complete":{"post":{"summary":"/mfa/totp/setup/complete","operationId":"postMfaTotpSetupComplete","description":"🔒 Authenticated with MFA JWT (scope: mfa:2fa)\n\nCompletes TOTP setup (JWT variant) by validating the Redis verification flag for the current secret, then persisting the secret to the database as enabled and verified. Cleans up temporary Redis entries.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model188"}}],"tags":["totp"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model189"},"description":"Successful"}}}},"/mfa/totp/setup/verify":{"post":{"summary":"/mfa/totp/setup/verify","operationId":"postMfaTotpSetupVerify","description":"🔒 Authenticated with MFA JWT (scope: mfa:2fa)\n\nVerifies an authenticator app code against the in-progress TOTP secret stored in Redis during setup, using an MFA JWT. On success, marks the setup as verified in Redis and aligns TTLs.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model190"}}],"tags":["totp"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model191"},"description":"Successful"}}}},"/oauth/subscriptions/iap/app-store-notification":{"post":{"summary":"/oauth/subscriptions/iap/app-store-notification","operationId":"postOauthSubscriptionsIapAppstorenotification","description":"🔒 payload validated against Apple certificates\n\nUpdate stored purchase information with latest subscription status.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model192"}}],"tags":["Subscriptions"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/oauth/subscriptions/iap/rtdn":{"post":{"summary":"/oauth/subscriptions/iap/rtdn","operationId":"postOauthSubscriptionsIapRtdn","description":"Handles a Google Play Real-time Developer Notification.","parameters":[{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model193"}}],"tags":["Subscriptions"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/oauth/subscriptions/stripe/event":{"post":{"summary":"/oauth/subscriptions/stripe/event","operationId":"postOauthSubscriptionsStripeEvent","description":"Handles webhook events from Stripe by pre-processing the incoming event and dispatching to the appropriate sub-handler.","parameters":[{"type":"string","name":"stripe-signature","in":"header","required":true}],"tags":["Subscriptions"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/oauth/subscriptions/iap/app-store-transaction/{appName}":{"post":{"summary":"/oauth/subscriptions/iap/app-store-transaction/{appName}","operationId":"postOauthSubscriptionsIapAppstoretransactionAppname","description":"🔒 authenticated with OAuth bearer token\n\nValidate and store an App Store Original Transaction ID for the given user. Returns token validity.","parameters":[{"type":"string","name":"appName","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model194"}}],"tags":["Subscriptions"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/oauth/subscriptions/iap/play-token/{appName}":{"post":{"summary":"/oauth/subscriptions/iap/play-token/{appName}","operationId":"postOauthSubscriptionsIapPlaytokenAppname","description":"🔒 Authenticated with OAuth bearer token\n\nValidate and store a Play Store Puchase Token for the given user. Returns token validity.","parameters":[{"type":"string","name":"appName","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model195"}}],"tags":["Subscriptions"],"responses":{"default":{"schema":{"type":"string"},"description":"Successful"}}}},"/passkey/{credentialId}":{"delete":{"summary":"/passkey/{credentialId}","operationId":"deletePasskeyCredentialid","description":"🔒 Authenticated with MFA JWT (scope: mfa:passkey)\n\nDeletes the passkey identified by `credentialId` (base64url-encoded).\nThe service validates that the passkey exists and belongs to the\nauthenticated user. Returns 404 if the passkey is not found or is\nnot owned by the user.\n\n**Params:**\n- `credentialId` (string, required) — base64url-encoded credential ID\n\n**Security event:** `account.passkey.removed` is recorded on success.","parameters":[{"type":"string","maxLength":1364,"pattern":"^[A-Za-z0-9_-]+$","name":"credentialId","in":"path","required":true}],"tags":["Passkeys"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model198"},"description":"Successful"}}},"patch":{"summary":"/passkey/{credentialId}","operationId":"patchPasskeyCredentialid","description":"🔒 Authenticated with MFA JWT (scope: mfa:passkey)\n\nRenames the passkey identified by `credentialId` (base64url-encoded).\nThe new name must be 1–255 characters and non-empty after trimming.\nThe service validates that the passkey exists and belongs to the\nauthenticated user. Returns 404 if the passkey is not found or is\nnot owned by the user.\n\n**Params:**\n- `credentialId` (string, required) — base64url-encoded credential ID\n\n**Request body:**\n- `name` (string, required) — new display name (1–255 chars)\n\n**Response:** the updated passkey, the same shape `GET /passkeys` returns.","parameters":[{"type":"string","maxLength":1364,"pattern":"^[A-Za-z0-9_-]+$","name":"credentialId","in":"path","required":true},{"in":"body","name":"body","schema":{"$ref":"#/definitions/Model200"}}],"tags":["Passkeys"],"responses":{"200":{"schema":{"$ref":"#/definitions/Model4"},"description":"Successful"}}}}},"definitions":{"Model1":{"type":"object","properties":{"email":{"type":"string"},"isPrimary":{"type":"boolean"},"verified":{"type":"boolean"}},"required":["email","isPrimary","verified"]},"emails":{"type":"array","items":{"$ref":"#/definitions/Model1"}},"Model2":{"type":"object","properties":{"providerId":{"type":"number"},"authAt":{"type":"number"},"enabled":{"type":"boolean"}},"required":["providerId","authAt","enabled"]},"linkedAccounts":{"type":"array","items":{"$ref":"#/definitions/Model2"}},"totp":{"type":"object","properties":{"exists":{"type":"boolean"},"verified":{"type":"boolean"}},"required":["exists","verified"]},"backupCodes":{"type":"object","properties":{"hasBackupCodes":{"type":"boolean"},"count":{"type":"number"}},"required":["hasBackupCodes","count"]},"recoveryKey":{"type":"object","properties":{"exists":{"type":"boolean"},"estimatedSyncDeviceCount":{"type":"number"}},"required":["exists"]},"recoveryPhone":{"type":"object","properties":{"exists":{"type":"boolean"},"phoneNumber":{"type":"string","pattern":"^(?:\\D*\\d){0,4}\\D*$"},"nationalFormat":{"type":"string","pattern":"^(?:\\D*\\d){0,4}\\D*$"},"available":{"type":"boolean"}},"required":["exists","available"]},"Model3":{"type":"object","properties":{"name":{"type":"string"},"createdAt":{"type":"number"},"verified":{"type":"boolean"}},"required":["name","createdAt","verified"]},"securityEvents":{"type":"array","items":{"$ref":"#/definitions/Model3"}},"transports":{"type":"array","items":{"type":"string"}},"Model4":{"type":"object","properties":{"credentialId":{"type":"string","maxLength":1364,"pattern":"^[A-Za-z0-9_-]+$"},"name":{"type":"string"},"createdAt":{"type":"number"},"lastUsedAt":{"type":"number"},"transports":{"$ref":"#/definitions/transports"},"aaguid":{"type":"string","pattern":"^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$"},"backupEligible":{"type":"boolean"},"backupState":{"type":"boolean"},"prfEnabled":{"type":"boolean"},"hasPasswordlessSync":{"type":"boolean"}},"required":["credentialId","name","createdAt","lastUsedAt","transports","aaguid","backupEligible","backupState","prfEnabled"]},"passkeys":{"type":"array","items":{"$ref":"#/definitions/Model4"}},"_subscription_type":{"type":"string","enum":["web"]},"period":{"type":"object","properties":{"end":{"type":"number"},"start":{"type":"number"}},"required":["end","start"]},"Model5":{"type":"object","properties":{"amount":{"type":"number"},"currency":{"type":"string"},"id":{"type":"string"},"name":{"type":"string"},"period":{"$ref":"#/definitions/period"}},"required":["amount","currency","id","name","period"]},"line_items":{"type":"array","items":{"$ref":"#/definitions/Model5"}},"Model6":{"type":"object","properties":{"amount":{"type":"number"},"inclusive":{"type":"boolean"},"display_name":{"type":"string"}},"required":["amount","inclusive"]},"tax":{"type":"array","items":{"$ref":"#/definitions/Model6"}},"discount":{"type":"object","properties":{"amount":{"type":"number"},"amount_off":{"type":"number"},"percent_off":{"type":"number"}},"required":["amount","amount_off","percent_off"]},"latest_invoice_items":{"type":"object","properties":{"line_items":{"$ref":"#/definitions/line_items"},"subtotal":{"type":"number"},"subtotal_excluding_tax":{"type":"number"},"total":{"type":"number"},"total_excluding_tax":{"type":"number"},"tax":{"$ref":"#/definitions/tax"},"discount":{"$ref":"#/definitions/discount"},"one_time_charge":{"type":"number"},"prorated_amount":{"type":"number"}},"required":["line_items","subtotal","total"]},"priceInfo":{"type":"object","properties":{"amount":{"type":"number"},"currency":{"type":"string"},"interval":{"type":"string"},"interval_count":{"type":"number"}},"required":["amount","currency","interval","interval_count"]},"Model7":{"type":"object","properties":{"_subscription_type":{"$ref":"#/definitions/_subscription_type"},"created":{"type":"number","description":"This is the date the subscription was created."},"current_period_end":{"type":"number","description":"This is the end date of the current billing cycle."},"current_period_start":{"type":"number","description":"This is the start date of the current billing cycle."},"cancel_at_period_end":{"type":"boolean","description":"True if the subscription will not automatically renew at the end of the current billing period. Else false."},"end_at":{"type":"number","x-alternatives":[{"type":"number"},{"type":"string"}]},"failure_code":{"type":"string","description":"Reason for the failure (e.g. insufficient funds, closed, frozen)."},"failure_message":{"type":"string","description":"Message from Stripe for the client making the request to further explain the reason for top-up failure if available.\n\nFor more information about failure codes and messages from Stripe to the client, see [Stripe docs](https://stripe.com/docs/api/errors). It is suggested that the [error type](https://stripe.com/docs/api/errors#errors-message) of `type: card_error` is shown directly to the customer."},"latest_invoice":{"type":"string","description":"The most recent invoice this subscription has generated from Stripe."},"latest_invoice_items":{"$ref":"#/definitions/latest_invoice_items"},"plan_id":{"type":"string","description":"A unique identifier for the [plan](https://stripe.com/docs/api/plans/object).","maxLength":255},"product_id":{"type":"string","description":"A unique identifier for the [product](https://stripe.com/docs/api/products/object) purchased.","maxLength":255},"product_name":{"type":"string","description":"The name of the product purchased."},"priceInfo":{"$ref":"#/definitions/priceInfo"},"status":{"type":"string","description":"The status of the product (e.g. `active`, `canceled`, `trialing`, `unpaid`, etc)."},"subscription_id":{"type":"string","description":"A unique identifier for the Stripe [subscription](https://stripe.com/docs/api/subscriptions/object).","maxLength":255},"promotion_amount_off":{"type":"integer","description":"Amount (in the currency specified) that will be taken off the subtotal of any invoices for this customer.","minimum":0},"promotion_code":{"type":"string","description":"A customer-redeemable code for a coupon."},"promotion_duration":{"type":"string","description":"Indicates how long the coupon is valid for."},"promotion_end":{"type":"number","description":"If the coupon has a duration of repeating, the date that this discount will end. If the coupon has a duration of once or forever, this attribute will be null."},"promotion_name":{"type":"string","description":"Name of the coupon displayed to customers on for instance invoices or receipts."},"promotion_percent_off":{"type":"number","description":"Percent that will be taken off the subtotal of any invoices for this customer for the duration of the coupon. For example, a coupon with percent_off of 50 will make a $100 invoice $50 instead.","minimum":0,"maximum":100}},"required":["created","current_period_end","current_period_start","cancel_at_period_end","latest_invoice","latest_invoice_items","plan_id","product_id","product_name","status","subscription_id"]},"subscriptions":{"type":"array","items":{"$ref":"#/definitions/Model7"}},"Model8":{"type":"object","properties":{"createdAt":{"type":"number"},"passwordCreatedAt":{"type":"number"},"metricsOptOutAt":{"type":"number"},"hasPassword":{"type":"boolean"},"emails":{"$ref":"#/definitions/emails"},"linkedAccounts":{"$ref":"#/definitions/linkedAccounts"},"totp":{"$ref":"#/definitions/totp"},"backupCodes":{"$ref":"#/definitions/backupCodes"},"recoveryKey":{"$ref":"#/definitions/recoveryKey"},"recoveryPhone":{"$ref":"#/definitions/recoveryPhone"},"securityEvents":{"$ref":"#/definitions/securityEvents"},"passkeys":{"$ref":"#/definitions/passkeys"},"subscriptions":{"$ref":"#/definitions/subscriptions"}}},"Model9":{"type":"array","items":{"$ref":"#/definitions/Model4"}},"recoveryCodes":{"type":"array","minItems":1,"maxItems":8,"x-constraint":{"unique":true},"items":{"type":"string","minLength":8,"maxLength":20,"pattern":"^[a-zA-Z0-9]*$"}},"Model10":{"type":"object","properties":{"recoveryCodes":{"$ref":"#/definitions/recoveryCodes"}},"required":["recoveryCodes"]},"Model11":{"type":"object","properties":{"verified":{"type":"boolean"},"isPrimary":{"type":"boolean"},"email":{"type":"string","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"}},"required":["verified","isPrimary","email"]},"Model12":{"type":"array","items":{"$ref":"#/definitions/Model11"}},"Model13":{"type":"object","properties":{"exists":{"type":"boolean"},"phoneNumber":{"type":"string","pattern":"^(?:\\D*\\d){0,4}\\D*$"},"nationalFormat":{"type":"string","pattern":"^(?:\\D*\\d){0,4}\\D*$"}},"required":["exists"]},"scope":{"type":"array","items":{"type":"string","maxLength":256,"pattern":"^[\\x21\\x23-\\x5B\\x5D-\\x7E]+$"}},"location":{"type":"object","description":"Object containing the client's state and country","properties":{"city":{"type":"string"},"country":{"type":"string"},"state":{"type":"string"},"stateCode":{"type":"string"}}},"Model14":{"type":"object","properties":{"clientId":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"deviceId":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":32}},"sessionTokenHandle":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"refreshTokenId":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"isCurrentSession":{"type":"boolean"},"deviceType":{"type":"string","maxLength":16},"name":{"type":"string","maxLength":255},"createdTime":{"type":"number","minimum":0},"createdTimeFormatted":{"type":"string"},"lastAccessTime":{"type":"number","minimum":0},"lastAccessTimeFormatted":{"type":"string"},"approximateLastAccessTime":{"type":"number","minimum":0},"approximateLastAccessTimeFormatted":{"type":"string"},"scope":{"$ref":"#/definitions/scope"},"location":{"$ref":"#/definitions/location"},"userAgent":{"type":"string","maxLength":255},"os":{"type":"string","maxLength":255}},"required":["clientId","deviceId","sessionTokenHandle","refreshTokenId","isCurrentSession","deviceType","name","createdTime","lastAccessTime","scope","userAgent"]},"Model15":{"type":"array","items":{"$ref":"#/definitions/Model14"}},"Model16":{"type":"object","properties":{"clientId":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"lastAccessTime":{"type":"number","minimum":0}},"required":["clientId","lastAccessTime"]},"Model17":{"type":"array","x-constraint":{"unique":{"ignoreUndefined":true}},"items":{"$ref":"#/definitions/Model16"}},"Model18":{"type":"object","properties":{"id":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":32}},"isCurrentDevice":{"type":"boolean"},"lastAccessTime":{"type":"number","minimum":0},"lastAccessTimeFormatted":{"type":"string"},"approximateLastAccessTime":{"type":"number","minimum":0},"approximateLastAccessTimeFormatted":{"type":"string"},"location":{"$ref":"#/definitions/location"},"name":{"type":"string","maxLength":255},"type":{"type":"string","maxLength":16},"pushCallback":{"type":"string","maxLength":255,"pattern":"^https:\\/\\/[a-zA-Z0-9._-]+(\\.services\\.mozilla\\.com|autopush\\.dev\\.mozaws\\.net|autopush\\.stage\\.mozaws\\.net)(?::\\d+)?(\\/.*)?$","x-format":{"uri":{"scheme":"https"}}},"pushPublicKey":{"type":"string","maxLength":88,"pattern":"^[A-Za-z0-9_-]+$"},"pushAuthKey":{"type":"string","maxLength":24,"pattern":"^[A-Za-z0-9_-]+$"},"pushEndpointExpired":{"type":"boolean"},"availableCommands":{"type":"object","properties":{"string":{"type":"string","maxLength":2048}}}},"required":["id","isCurrentDevice","lastAccessTime","name","type"]},"Model19":{"type":"array","items":{"$ref":"#/definitions/Model18"}},"Model20":{"type":"object","properties":{"originalEmail":{"type":"string"},"primaryEmail":{"type":"string"}},"required":["originalEmail","primaryEmail"]},"Model21":{"type":"object","properties":{"bundle":{"type":"string","description":"See [**decrypting the bundle**](https://wiki.mozilla.org/Identity/AttachedServices/KeyServerProtocol#Decrypting_the_getToken2_Response) for information on how to extract kA|wrapKb from the bundle.","pattern":"^(?:[a-fA-F0-9]{2})+$"}}},"additionalEmails":{"type":"array","items":{"type":"string"}},"authenticationMethods":{"type":"array","items":{"type":"string"}},"subscriptionsByClientId":{"type":"object"},"Model22":{"type":"object","properties":{"email":{"type":"string"},"additionalEmails":{"$ref":"#/definitions/additionalEmails"},"locale":{"type":"string"},"authenticationMethods":{"$ref":"#/definitions/authenticationMethods"},"authenticatorAssuranceLevel":{"type":"number","minimum":0},"subscriptionsByClientId":{"$ref":"#/definitions/subscriptionsByClientId"},"profileChangedAt":{"type":"number","minimum":0},"metricsEnabled":{"type":"boolean"},"accountLockedAt":{"type":"number"},"accountDisabledAt":{"type":"number"},"keysChangedAt":{"type":"number"}}},"Model23":{"type":"object","properties":{"id":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application) asking for permission.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16}},"name":{"type":"string","description":"A string name of the client."},"trusted":{"type":"boolean","description":"Whether the client is a trusted internal application."},"image_uri":{"type":"string","description":"A url to a logo or image that represents the client."},"redirect_uri":{"type":"string","description":"The URI at which the connecting client expects to receive the authorization code and redirect to after a successful oauth. If supplied, this must match the URL value provided during OAuth client registration."}},"required":["id","name","trusted","redirect_uri"]},"Model24":{"type":"object","properties":{"email":{"type":"string"},"verified":{"type":"boolean"},"sessionVerified":{"type":"boolean"},"emailVerified":{"type":"boolean"}},"required":["email","verified"]},"details":{"type":"object","properties":{"accountEmailVerified":{"type":"boolean"},"sessionVerificationMethod":{"type":"string"},"sessionVerified":{"type":"boolean"},"sessionVerificationMeetsMinimumAAL":{"type":"boolean"},"verified":{"type":"boolean"}}},"Model25":{"type":"object","properties":{"state":{"type":"string"},"uid":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"details":{"$ref":"#/definitions/details"}},"required":["state","uid"]},"Model26":{"type":"object","properties":{"exists":{"type":"boolean"},"verified":{"type":"boolean"}}},"payload":{"type":"object"},"data":{"type":"object","properties":{"command":{"type":"string","maxLength":255},"payload":{"$ref":"#/definitions/payload"},"sender":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":32}}},"required":["command","payload"]},"Model27":{"type":"object","properties":{"index":{"type":"number"},"data":{"$ref":"#/definitions/data"}},"required":["index","data"]},"messages":{"type":"array","description":"An array of individual commands for the device to process.","items":{"$ref":"#/definitions/Model27"}},"Model28":{"type":"object","properties":{"index":{"type":"number","description":"The largest index of the commands returned in this response. This value can be passed as the index parameter in subsequent calls in order to page through all the items."},"last":{"type":"boolean","description":"Indicates whether more commands and enqueued than could be returned within the specific limit."},"messages":{"$ref":"#/definitions/messages"}},"required":["index"]},"Model29":{"type":"object","properties":{"eligible":{"type":"boolean"}},"required":["eligible"]},"Model30":{"type":"object","properties":{"id":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application) asking for permission.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16}},"name":{"type":"string","description":"A string name of the client."},"trusted":{"type":"boolean","description":"Whether the client is a trusted internal application."},"image_uri":{"type":"string","description":"A url to a logo or image that represents the client."},"redirect_uri":{"type":"string","description":"The URI at which the connecting client expects to receive the authorization code and redirect to after a successful oauth. If supplied, this must match the URL value provided during OAuth client registration."}},"required":["id","name","trusted","redirect_uri"]},"Model31":{"type":"object","properties":{"uid":{"type":"string","description":"The user id."},"subscriptionId":{"type":"string","description":"A unique identifier for the Stripe [subscription](https://stripe.com/docs/api/subscriptions/object).","maxLength":255},"productId":{"type":"string","description":"A unique identifier for the [product](https://stripe.com/docs/api/products/object) purchased.","maxLength":255},"createdAt":{"type":"number","description":"This is the date the subscription was created."},"cancelledAt":{"type":"number","x-alternatives":[{"type":"number"},{"type":"string"}]}},"required":["uid","subscriptionId","productId","createdAt"]},"Model32":{"type":"array","items":{"$ref":"#/definitions/Model31"}},"capabilities":{"type":"array","description":"An array of RP-defined strings that represent a certain level of access to their product/service.","items":{"type":"string"}},"Model33":{"type":"object","properties":{"clientId":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application)"},"capabilities":{"$ref":"#/definitions/capabilities"}}},"Model34":{"type":"array","items":{"$ref":"#/definitions/Model33"}},"Model35":{"type":"object","properties":{"pkR":{"type":"string","maxLength":178,"pattern":"^[A-Za-z0-9_-]+$","x-constraint":{"length":178}},"prfWrappedSkR":{"type":"string","maxLength":110,"pattern":"^[A-Za-z0-9_-]+$","x-constraint":{"length":110}},"keyWrapIv":{"type":"string","maxLength":16,"pattern":"^[A-Za-z0-9_-]+$","x-constraint":{"length":16}},"hpkeEncapsulatedSecret":{"type":"string","maxLength":178,"pattern":"^[A-Za-z0-9_-]+$","x-constraint":{"length":178}},"hpkeSealedKb":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_-]+$","x-constraint":{"length":64}},"createdAt":{"type":"number"}},"required":["pkR","prfWrappedSkR","keyWrapIv","hpkeEncapsulatedSecret","hpkeSealedKb","createdAt"]},"response_type":{"type":"string","description":"If supplied, must be either code or token. code is the default. token means the implicit grant is desired, and requires that the client have special permission to do so.\n\n- Note: new implementations should not use `response_type=token`; instead use `grant_type=fxa-credentials` at the [token][] endpoint.","default":"code","enum":["code","token"]},"access_type":{"type":"string","description":"If specified, a value of `offline` will cause the connecting client to be granted a refresh token alongside its access token.","default":"online","enum":["offline","online"]},"code_challenge_method":{"type":"string","description":"Required for public OAuth clients, who must authenticate their authorization code use via [**PKCE**](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/fxa-oauth-server/docs/pkce.md). The only support method is 'S256', no other value is accepted.","enum":["S256"]},"prompt":{"type":"string","enum":["none","login","consent"]},"Model36":{"type":"object","properties":{"client_id":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application) returned from client registration.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16}},"assertion":{"type":"string","description":"A FxA assertion for the signed-in user.","minLength":50,"maxLength":10240,"pattern":"^[a-zA-Z0-9_\\-\\.~=]+$"},"redirect_uri":{"type":"string","description":"The URI at which the connecting client expects to receive the authorization code and redirect to after a successful oauth. If supplied, this must match the URL value provided during OAuth client registration.","maxLength":256,"x-format":{"uri":{"scheme":["https"]}}},"scope":{"type":"string","description":"A space-separated list of scope values that the user has authorized, or is held by the granted access token that the connecting client will be granted. The requested scope will be provided by the connecting client as part of its authorization request, but may be pruned by the user in a confirmation dialog before being sent to this endpoint."},"response_type":{"$ref":"#/definitions/response_type"},"state":{"type":"string","description":"An opaque string value provided by the connecting client application, which will be returned unmodified upon redirection alongside the authorization code. This can be used by the connecting client guard against certain classes of attack in the redirect-based OAuth flow to verify that the redirect is authentic.","maxLength":512},"ttl":{"type":"number","description":"Indicates the requested lifespan in seconds for the `access_token` or implicit grant token. If unspecified, the value will default to an internal maximum limit allowed by the server, which is a configurable option, so clients must check the `expires_in` result property for the actual TTL - it is typically measured in minutes or hours.undefined","default":86400,"x-constraint":{"sign":"positive"}},"access_type":{"$ref":"#/definitions/access_type"},"code_challenge_method":{"$ref":"#/definitions/code_challenge_method"},"code_challenge":{"type":"string","description":"Required for public OAuth clients, who must authenticate their authorization code use via [**PKCE**](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/fxa-oauth-server/docs/pkce.md). A minimum length of 43 characters and a maximum length of 128 characters string, encoded as `BASE64URL`.","x-constraint":{"length":43}},"keys_jwe":{"type":"string","description":"An encrypted JWE bundle of key material, to be returned to the client when it redeems the authorization code.","maxLength":1024,"pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$"},"acr_values":{"type":"string","description":"A space-separated list of ACR values specifying acceptable levels of user authentication that the token should have a claim for. Specifying `AAL2` will require the token to have an authentication assurance level >= 2, which ensures the user has completed a second factor before the requested grant is authorized. `AAL2` is the only value recognized; any other value in the list is ignored.","maxLength":256},"max_age":{"type":"integer","description":"The maximum permissible elapsed time in seconds since the user last authenticated. If the session is older, a fresh second-factor challenge (step-up authentication) is required before the grant is authorized. Freshness is measured against the session's most recent authentication event, and is evaluated with a five-second grace period so that a just-completed challenge satisfies `max_age=0`.","minimum":0},"resource":{"type":"string","description":"Indicates the target service or resource at which access is being requested. Its value must be an absolute URI, and may include a query component but must not include a fragment component. Added to the `aud` claim of JWT access tokens. Optional if `response_type=token`, forbidden if `response_type=code`.","pattern":"#","x-format":{"uri":true}},"service":{"type":"string","description":"Opaque alphanumeric token to be included in verification links.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"prompt":{"$ref":"#/definitions/prompt"}},"required":["client_id","assertion","scope","code_challenge_method"]},"token_type":{"type":"string","description":"The type of token, which determines how the client should use it in subsequent requests. Currently only Bearer tokens are supported.","enum":["bearer"]},"Model37":{"type":"object","properties":{"redirect":{"type":"string"},"code":{"type":"string","description":"A string that the client will trade with the [token][] endpoint. Codes have a configurable expiration value, default is 15 minutes. Codes are single use only."},"state":{"type":"string","description":"An opaque string value provided by the connecting client application, which will be returned unmodified upon redirection alongside the authorization code. This can be used by the connecting client guard against certain classes of attack in the redirect-based OAuth flow to verify that the redirect is authentic."},"access_token":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64},"x-alternatives":[{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},{"type":"string","maxLength":2048,"pattern":"^([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)$"}]},"token_type":{"$ref":"#/definitions/token_type"},"scope":{"type":"string","description":"A space-separated list of scope values that the user has authorized, or is held by the granted access token that the connecting client will be granted. The requested scope will be provided by the connecting client as part of its authorization request, but may be pruned by the user in a confirmation dialog before being sent to this endpoint."},"auth_at":{"type":"number","description":"The UTC unix timestamp for the session at which the user last authenticated to FxA server when generating this token, in seconds since the epoch."},"expires_in":{"type":"number","description":"The number of seconds until the access token will expire."}}},"Model38":{"type":"object","properties":{"client_id":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application)","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16}},"client_secret":{"type":"string","description":"The OAuth client secret for the requesting client application. Required for confidential clients, forbidden for public clients.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},"access_token":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64},"x-alternatives":[{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},{"type":"string","maxLength":2048,"pattern":"^([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)$"}]},"refresh_token":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},"refresh_token_id":{"type":"string","description":"The specific `refresh_token_id` to be destroyed.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}}}},"token_type_hint":{"type":"string","description":"A hint as to what type of token is being revoked. Expected values are \"access_token\" or \"refresh_token\", Unrecognized values will be silently ignored, and specifying an incorrect hint may cause to the request to take longer but will still result in the token being destroyed.","enum":["access_token","refresh_token"]},"Model39":{"type":"object","properties":{"token":{"type":"string","description":"An OAuth token string received from a client for the user"},"token_type_hint":{"$ref":"#/definitions/token_type_hint"}},"required":["token"]},"Model40":{"type":"string","description":"A string representing the token type. It will be `access_token` or `refresh_token`","enum":["access_token","refresh_token"]},"amr":{"type":"array","description":"The authentication methods used for this grant, as an array of method classes (for example `[\"pwd\",\"otp\"]`). Method classes are coarse: TOTP, backup authentication codes, and recovery-phone codes all report as `otp`.","items":{"type":"string"}},"Model41":{"type":"object","properties":{"active":{"type":"boolean","description":"Boolean indicator of whether the presented token is active."},"scope":{"type":"string","description":"A space-separated list of scope values that the user has authorized, or is held by the granted access token that the connecting client will be granted. The requested scope will be provided by the connecting client as part of its authorization request, but may be pruned by the user in a confirmation dialog before being sent to this endpoint."},"client_id":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application)","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16}},"token_type":{"$ref":"#/definitions/Model40"},"exp":{"type":"number","description":"Integer time of token expiration."},"iat":{"type":"number","description":"Integer time of token creation."},"sub":{"type":"string","description":"The hex id of the user."},"iss":{"type":"string"},"jti":{"type":"string","description":"The hex id of the token."},"fxa-lastUsedAt":{"type":"number","description":" Integer time when this token is last used."},"acr":{"type":"string","description":"The authentication context class reference reached by the session that produced this grant, as a string of the form `AAL2`. Reflects the assurance level actually achieved, which may be higher than the level requested."},"auth_time":{"type":"number","description":"The time of the session's most recent authentication event, in seconds since the epoch. Note that `iat` and `exp` on this endpoint are in milliseconds; the difference is intentional and retained for backwards compatibility."},"amr":{"$ref":"#/definitions/amr"}},"required":["active"]},"Model42":{"type":"string","enum":["firefox-accounts-journey","knowledge-is-power","mozilla-foundation","take-action-for-the-internet","test-pilot","mozilla-and-you","security-privacy-news","mozilla-accounts","hubs","mdnplus"]},"newsletters":{"type":"array","items":{"$ref":"#/definitions/Model42"}},"Model43":{"type":"object","properties":{"newsletters":{"$ref":"#/definitions/newsletters"}},"required":["newsletters"]},"Model44":{"type":"object","properties":{"success":{"type":"boolean"}}},"Model45":{"type":"object","properties":{"recoveryKeyId":{"type":"string","description":"A unique identifier for this account recovery key, derived from the key via HKDF.","maxLength":32,"pattern":"^(?:[a-fA-F0-9]{2})+$"},"recoveryData":{"type":"string","description":"An encrypted bundle containing the user's kB.","maxLength":1024,"pattern":"[a-zA-Z0-9.]"},"enabled":{"type":"boolean","default":true},"replaceKey":{"type":"boolean","default":false}},"required":["recoveryData"]},"grant_type":{"type":"string","description":"- If `authorization_code`:\n  - `client_id`: The id returned from client registration.\n  - `client_secret`: The secret returned from client registration. Forbidden for public clients, required otherwise.\n  - `code`: A string that was received from the [authorization][] endpoint.\n  - `code_verifier`: The [PKCE](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/docs/oauth/pkce.md) code verifier. Required for public clients, forbidden otherwise.\n- If `refresh_token`:\n  - `client_id`: The id returned from client registration.\n  - `client_secret`: The secret returned from client registration. Forbidden for public (PKCE) clients, required otherwise.\n  - `refresh_token`: A string that received from the [token][] endpoint specifically as a refresh token.\n  - `scope`: (optional) A subset of scopes provided to this refresh_token originally, to receive an access_token with less permissions.\n- If `fxa-credentials`:\n  - `client_id`: The id returned from client registration.\n  - `assertion`: FxA identity assertion authenticating the user.\n  - `scope`: (optional) A string-separated list of scopes to be authorized.\n  - `access_type`: (optional) Determines whether to generate a `refresh_token` (if `offline`) or not (if `online`).","default":"authorization_code","enum":["authorization_code","refresh_token","fxa-credentials","urn:ietf:params:oauth:grant-type:token-exchange"]},"subject_token_type":{"type":"string","description":"A URN identifying the type of subject_token. Must be `urn:ietf:params:oauth:token-type:refresh_token` to indicate the subject_token is a refresh token.","enum":["urn:ietf:params:oauth:token-type:refresh_token"]},"Model46":{"type":"object","properties":{"client_id":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application)","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16}},"client_secret":{"type":"string","description":"The OAuth client secret for the requesting client application. Required for confidential clients, forbidden for public clients.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},"redirect_uri":{"type":"string","description":"The URI at which the connecting client expects to receive the authorization code and redirect to after a successful oauth. If supplied, this must match the URL value provided during OAuth client registration.","maxLength":256,"pattern":"^[a-zA-Z0-9\\-_\\/.:?=&]+$"},"grant_type":{"$ref":"#/definitions/grant_type"},"ttl":{"type":"number","description":"Indicates the requested lifespan in seconds for the `access_token` or implicit grant token. If unspecified, the value will default to an internal maximum limit allowed by the server, which is a configurable option, so clients must check the `expires_in` result property for the actual TTL - it is typically measured in minutes or hours.","default":86400,"x-constraint":{"sign":"positive"}},"scope":{"type":"string","required":["scope"],"optional":["scope"],"x-alternatives":[{"type":"string"},{"type":"string"},{"type":"string"}]},"access_type":{"$ref":"#/definitions/access_type"},"code":{"type":"string","description":"A string that the client will trade with the [token][] endpoint. Codes have a configurable expiration value, default is 15 minutes. Codes are single use only.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},"code_verifier":{"type":"string","description":"The [PKCE](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/docs/oauth/pkce.md) code verifier. Required for public clients, forbidden otherwise.","minLength":43,"maxLength":128,"pattern":"^[A-Za-z0-9-_]+$"},"refresh_token":{"type":"string","description":"A token that can be used to grant a new access token when the current one expires, via `grant_type=refresh_token` on this endpoint.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},"assertion":{"type":"string","description":"A FxA assertion for the signed-in user.","minLength":50,"maxLength":10240,"pattern":"^[a-zA-Z0-9_\\-\\.~=]+$"},"subject_token":{"type":"string","description":"The token to be exchanged. Used with `grant_type=urn:ietf:params:oauth:grant-type:token-exchange` per RFC 8693.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},"subject_token_type":{"$ref":"#/definitions/subject_token_type"},"ppid_seed":{"type":"integer","description":"Seed used in `sub` claim generation of JWT access tokens/ID tokens for clients with [Pseudonymous Pairwise Identifiers (PPID)](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/docs/oauth/pairwise-pseudonymous-identifiers.md) enabled. Used to forcibly rotate the `sub` claim. Must be an integer in the range 0-1024. If not specified, it will default to `0`.","default":0,"minimum":0,"maximum":1024},"resource":{"type":"string","description":"Indicates the target service or resource at which access is being requested. Its value must be an absolute URI, and may include a query component but must not include a fragment component. Added to the `aud` claim of JWT access tokens.","pattern":"#","x-format":{"uri":true}}},"required":["client_id","client_secret","code","refresh_token","assertion","subject_token","subject_token_type"]},"Model47":{"type":"object","properties":{"access_token":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64},"x-alternatives":[{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},{"type":"string","maxLength":2048,"pattern":"^([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)$"}]},"refresh_token":{"type":"string","description":"A refresh token to fetch a new access token when this one expires. Only present if:\n\n- `grant_type=authorization_code` and the original authorization request included `access_type=offline`.\n- `grant_type=fxa-credentials` and the request included `access_type=offline`.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},"id_token":{"type":"string","description":"OpenID Connect identity token, provisioned if the authorization was requested with `openid` scope.","minLength":50,"maxLength":10240,"pattern":"^[a-zA-Z0-9_\\-\\.~=]+$"},"session_token_id":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"scope":{"type":"string","description":"A space-separated list of scope values that the user has authorized, or is held by the granted access token that the connecting client will be granted. The requested scope will be provided by the connecting client as part of its authorization request, but may be pruned by the user in a confirmation dialog before being sent to this endpoint."},"token_type":{"$ref":"#/definitions/token_type"},"expires_in":{"type":"number","description":"The number of seconds until the access token will expire.","maximum":86400},"auth_at":{"type":"number","description":"The UTC unix timestamp for the session at which the user last authenticated to FxA server when generating this token, in seconds since the epoch."},"keys_jwe":{"type":"string","description":"Returns the JWE bundle of key material for any scopes that have keys, if `grant_type=authorization_code`","maxLength":1024,"pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$"}},"required":["access_token","scope","token_type","expires_in"]},"Model48":{"type":"object","properties":{"token":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64},"x-alternatives":[{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},{"type":"string","maxLength":2048,"pattern":"^([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)$"}]}},"required":["token"]},"Model49":{"type":"array","description":"A space-separated list of scope values that the user has authorized, or is held by the granted access token that the connecting client will be granted. The requested scope will be provided by the connecting client as part of its authorization request, but may be pruned by the user in a confirmation dialog before being sent to this endpoint.","items":{"type":"string"}},"Model50":{"type":"object","properties":{"user":{"type":"string","description":"The uid of the respective user."},"client_id":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application)"},"scope":{"$ref":"#/definitions/Model49"},"generation":{"type":"number","minimum":0},"profile_changed_at":{"type":"number","minimum":0}},"required":["user","client_id"]},"utmCampaign":{"type":"string","enum":["page+referral+-+not+part+of+a+campaign"],"maxLength":128,"pattern":"^[\\w\\/.%-]+$"},"metricsContext":{"type":"object","properties":{"deviceId":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":32}},"entrypoint":{"type":"string","maxLength":128,"pattern":"^[\\w.:-]+$"},"entrypointExperiment":{"type":"string","maxLength":128,"pattern":"^[\\w.:-]+$"},"entrypointVariation":{"type":"string","maxLength":128,"pattern":"^[\\w.:-]+$"},"flowId":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"flowBeginTime":{"type":"integer","x-constraint":{"sign":"positive"}},"utmCampaign":{"$ref":"#/definitions/utmCampaign"},"utmContent":{"type":"string","maxLength":128,"pattern":"^[\\w\\/.%-]+$"},"utmMedium":{"type":"string","maxLength":128,"pattern":"^[\\w\\/.%-]+$"},"utmSource":{"type":"string","maxLength":128,"pattern":"^[\\w\\/.%-]+$"},"utmTerm":{"type":"string","maxLength":128,"pattern":"^[\\w\\/.%-]+$"},"productId":{"type":"string","maxLength":128},"planId":{"type":"string","maxLength":128},"clientId":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":16}},"service":{"type":"string","maxLength":128}}},"style":{"type":"string","enum":["trailhead"]},"verificationMethod":{"type":"string","description":"If this param is specified, it forces the login to be verified using the specified method.\nCurrently supported methods:\n- `email`: Sends an email with a confirmation link.\n- `email-2fa`: Sends an email with a confirmation code.\n- `email-captcha`: Sends an email with an unblock code.","enum":["email","email-otp","email-2fa","email-captcha","totp-2fa"]},"Model51":{"type":"object","properties":{"email":{"type":"string","description":"The primary email for this account.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"authPW":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"authPWVersion2":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string using the version 2 key stretching.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"wrapKb":{"type":"string","description":"The new `wrapKb` value as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"wrapKbVersion2":{"type":"string","description":"The new `wrapKb` value for authPW2 as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"clientSalt":{"type":"string","description":"The salt used when creating authPW. If not provided, it will be assumed that version one of the password encryption scheme was used.","pattern":"^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretch:|^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretchV2:"},"service":{"type":"string","description":"Opaque alphanumeric token to be included in verification links.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"redirectTo":{"type":"string","description":"URL that the client should be redirected to after handling the request.","maxLength":2048},"resume":{"type":"string","description":"Opaque URL-encoded string to be included in the verification link as a query parameter.","maxLength":2048},"metricsContext":{"$ref":"#/definitions/metricsContext"},"style":{"$ref":"#/definitions/style"},"verificationMethod":{"$ref":"#/definitions/verificationMethod"}},"required":["email","authPW"]},"Model52":{"type":"object","properties":{"uid":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"sessionToken":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"keyFetchToken":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"keyFetchTokenVersion2":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"authAt":{"type":"integer","description":"The UTC unix timestamp for the session at which the user last authenticated to FxA server when generating this token, in seconds since the epoch."},"verificationMethod":{"$ref":"#/definitions/verificationMethod"}},"required":["uid","sessionToken"]},"Model53":{"type":"object","properties":{"email":{"type":"string","description":"The primary email for this account.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"authPW":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}}},"required":["email","authPW"]},"Model54":{"type":"array","x-constraint":{"length":0},"items":{"type":"string"}},"Model55":{"type":"object","properties":{"id":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":32}},"name":{"type":"string","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"type":{"type":"string","maxLength":16},"pushCallback":{"type":"string","maxLength":255,"pattern":"^https:\\/\\/[a-zA-Z0-9._-]+(\\.services\\.mozilla\\.com|autopush\\.dev\\.mozaws\\.net|autopush\\.stage\\.mozaws\\.net)(?::\\d+)?(\\/.*)?$","x-format":{"uri":{"scheme":"https"}}},"pushPublicKey":{"type":"string","maxLength":88,"pattern":"^[A-Za-z0-9_-]+$"},"pushAuthKey":{"type":"string","maxLength":24,"pattern":"^[A-Za-z0-9_-]+$"},"availableCommands":{"type":"object","properties":{"string":{"type":"string","maxLength":2048}}},"capabilities":{"$ref":"#/definitions/Model54"}}},"Model56":{"type":"object","properties":{"id":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":32}},"createdAt":{"type":"number","x-constraint":{"sign":"positive"}},"name":{"type":"string","maxLength":255},"type":{"type":"string","maxLength":16},"pushCallback":{"type":"string","maxLength":255,"pattern":"^https:\\/\\/[a-zA-Z0-9._-]+(\\.services\\.mozilla\\.com|autopush\\.dev\\.mozaws\\.net|autopush\\.stage\\.mozaws\\.net)(?::\\d+)?(\\/.*)?$","x-format":{"uri":{"scheme":"https"}}},"pushPublicKey":{"type":"string","maxLength":88,"pattern":"^[A-Za-z0-9_-]+$"},"pushAuthKey":{"type":"string","maxLength":24,"pattern":"^[A-Za-z0-9_-]+$"},"pushEndpointExpired":{"type":"boolean"},"availableCommands":{"type":"object","properties":{"string":{"type":"string","maxLength":2048}}}},"required":["id"]},"Model57":{"type":"object","properties":{"email":{"type":"string","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"}},"required":["email"]},"Model58":{"type":"object","properties":{"hasHardBounce":{"type":"boolean"}},"required":["hasHardBounce"]},"Model59":{"type":"object","properties":{"email":{"type":"string","description":"The primary email for this account.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"authPW":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"service":{"type":"string","description":"Opaque alphanumeric token to be included in verification links.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"redirectTo":{"type":"string","maxLength":2048},"resume":{"type":"string","description":"Opaque URL-encoded string to be included in the verification link as a query parameter."},"reason":{"type":"string","description":"Alphanumeric string indicating the reason for establishing a new session; may be \"login\" (the default) or \"reconnect\".","maxLength":16},"unblockCode":{"type":"string","description":"Alphanumeric code used to unblock certain rate-limitings.","pattern":"^[a-zA-Z0-9]*$","x-constraint":{"length":8}},"metricsContext":{"$ref":"#/definitions/metricsContext"},"originalLoginEmail":{"type":"string","description":"This parameter is the original email used to login with. Typically, it is specified after a user logins with a different email case, or changed their primary email address.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"verificationMethod":{"$ref":"#/definitions/verificationMethod"},"sendSigninVerificationEmail":{"type":"boolean","description":"Whether the server should send the sign-in verification code email. Defaults to\n`true` when omitted, so clients integrating with this API directly keep receiving\nit — including those that render their own verification UI, which this send exists\nfor. Set to `false` if the caller sends the code itself (via `/session/resend_code`)\nwhen it presents the code entry screen, as FxA's own web front-end does. Applies\nonly to the `verifyLoginCode` email; link-based confirmation emails are unaffected."}},"required":["email","authPW"]},"Model60":{"type":"object","properties":{"uid":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"sessionToken":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"keyFetchToken":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"keyFetchTokenVersion2":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"verificationMethod":{"type":"string","description":"If this param is specified, it forces the login to be verified using the specified method.\nCurrently supported methods:\n- `email`: Sends an email with a confirmation link.\n- `email-2fa`: Sends an email with a confirmation code.\n- `email-captcha`: Sends an email with an unblock code."},"verificationReason":{"type":"string","description":"The authentication method that required additional verification."},"emailVerified":{"type":"boolean"},"sessionVerified":{"type":"boolean"},"verified":{"type":"boolean"},"authAt":{"type":"integer","description":"The UTC unix timestamp for the session at which the user last authenticated to FxA server when generating this token, in seconds since the epoch."},"metricsEnabled":{"type":"boolean"}},"required":["uid","sessionToken","emailVerified","sessionVerified","verified","metricsEnabled"]},"state":{"type":"string","enum":["in","out"]},"Model61":{"type":"object","properties":{"state":{"$ref":"#/definitions/state"}},"required":["state"]},"Model62":{"type":"object","properties":{"authPW":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"authPWVersion2":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"wrapKb":{"type":"string","description":"The new `wrapKb` value as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"wrapKbVersion2":{"type":"string","description":"The new `wrapKb` value for authPW2 as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"clientSalt":{"type":"string","description":"The salt used when creating authPW. If not provided, it will be assumed that version one of the password encryption scheme was used.","pattern":"^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretch:|^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretchV2:"},"recoveryKeyId":{"type":"string","description":"A unique identifier for this account recovery key, derived from the key via HKDF.","maxLength":32,"pattern":"^(?:[a-fA-F0-9]{2})+$"},"sessionToken":{"type":"boolean","description":"Indicates whether a new `sessionToken` is required, default to `false`."},"isFirefoxMobileClient":{"type":"boolean","description":"Is this a Firefox mobile client?"}},"required":["authPW"]},"Model63":{"type":"object","properties":{"client_id":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16}},"scope":{"type":"string"}},"required":["client_id","scope"]},"any":{"type":"object","properties":{"identifier":{"type":"string"},"keyRotationSecret":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"keyRotationTimestamp":{"type":"number"}},"required":["identifier","keyRotationSecret","keyRotationTimestamp"]},"Model64":{"type":"object","properties":{"email":{"type":"string","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"thirdPartyAuthStatus":{"type":"boolean","default":false},"checkDomain":{"type":"string"},"clientId":{"type":"string"},"service":{"type":"string","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"}},"required":["email"]},"Model65":{"type":"object","properties":{"exists":{"type":"boolean"},"hasLinkedAccount":{"type":"boolean"},"hasPassword":{"type":"boolean"},"hasPasskey":{"type":"boolean"},"invalidDomain":{"type":"boolean"},"passwordlessSupported":{"type":"boolean"}},"required":["exists"]},"provider":{"type":"string","enum":["google","apple"],"maxLength":256},"Model66":{"type":"object","properties":{"idToken":{"type":"string","maxLength":2048,"pattern":"^([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)$"},"provider":{"$ref":"#/definitions/provider"},"code":{"type":"string"},"metricsContext":{"$ref":"#/definitions/metricsContext"},"service":{"type":"string","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"}},"required":["provider"]},"Model67":{"type":"object","properties":{"uid":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"sessionToken":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"providerUid":{"type":"string","description":"The user id associated with a particular third party provider."},"email":{"type":"string","description":"The primary email for this account."},"verificationMethod":{"type":"string","description":"If this param is specified, it forces the login to be verified using the specified method.\nCurrently supported methods:\n- `email`: Sends an email with a confirmation link.\n- `email-2fa`: Sends an email with a confirmation code.\n- `email-captcha`: Sends an email with an unblock code."}},"required":["uid","sessionToken","providerUid","email"]},"Model68":{"type":"object","properties":{"provider":{"$ref":"#/definitions/provider"}},"required":["provider"]},"Model69":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]},"Model70":{"type":"object","properties":{"success":{"type":"boolean"}}},"Model71":{"type":"object","properties":{"recoveryKeyId":{"type":"string","description":"A unique identifier for this account recovery key, derived from the key via HKDF.","maxLength":32,"pattern":"^(?:[a-fA-F0-9]{2})+$"},"recoveryData":{"type":"string","description":"An encrypted bundle containing the user's kB.","maxLength":1024,"pattern":"[a-zA-Z0-9.]"},"enabled":{"type":"boolean","default":true},"replaceKey":{"type":"boolean","default":false}},"required":["recoveryData"]},"Model72":{"type":"object","properties":{"email":{"type":"string","description":"The email address to add to the account.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"}},"required":["email"]},"Model73":{"type":"string","description":"Determines the format of the response. Since we only support the authorization-code grant flow, the only permitted value is 'code'.","default":"code","enum":["code"]},"Model74":{"type":"object","properties":{"response_type":{"$ref":"#/definitions/Model73"},"client_id":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application)","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16}},"redirect_uri":{"type":"string","description":"The URI at which the connecting client expects to receive the authorization code and redirect to after a successful oauth. If supplied, this must match the URL value provided during OAuth client registration.","maxLength":256,"x-format":{"uri":{"scheme":["http","https"]}}},"scope":{"type":"string","description":"A space-separated list of scope values that the user has authorized, or is held by the granted access token that the connecting client will be granted. The requested scope will be provided by the connecting client as part of its authorization request, but may be pruned by the user in a confirmation dialog before being sent to this endpoint."},"state":{"type":"string","description":"An opaque string value provided by the connecting client application, which will be returned unmodified upon redirection alongside the authorization code. This can be used by the connecting client guard against certain classes of attack in the redirect-based OAuth flow to verify that the redirect is authentic.","maxLength":512},"access_type":{"$ref":"#/definitions/access_type"},"code_challenge_method":{"$ref":"#/definitions/code_challenge_method"},"code_challenge":{"type":"string","description":"Required for public OAuth clients, who must authenticate their authorization code use via [**PKCE**](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/fxa-oauth-server/docs/pkce.md). A minimum length of 43 characters and a maximum length of 128 characters string, encoded as `BASE64URL`.","pattern":"^[A-Za-z0-9_-]+$","x-constraint":{"length":43}},"keys_jwe":{"type":"string","description":"An encrypted JWE bundle of key material, to be returned to the client when it redeems the authorization code.","maxLength":1024,"pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$"},"acr_values":{"type":"string","description":"A space-separated list of ACR values specifying acceptable levels of user authentication that the token should have a claim for. Specifying `AAL2` will require the token to have an authentication assurance level >= 2, which ensures the user has completed a second factor before the requested grant is authorized. `AAL2` is the only value recognized; any other value in the list is ignored.","maxLength":256},"max_age":{"type":"integer","description":"The maximum permissible elapsed time in seconds since the user last authenticated. If the session is older, a fresh second-factor challenge (step-up authentication) is required before the grant is authorized. Freshness is measured against the session's most recent authentication event, and is evaluated with a five-second grace period so that a just-completed challenge satisfies `max_age=0`.","minimum":0},"service":{"type":"string","description":"Opaque alphanumeric token to be included in verification links.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"prompt":{"$ref":"#/definitions/prompt"}},"required":["client_id","state"]},"Model75":{"type":"object","properties":{"redirect":{"type":"string"},"code":{"type":"string"},"state":{"type":"string","maxLength":512},"scope":{"type":"string","description":"A space-separated list of scope values that the user has authorized, or is held by the granted access token that the connecting client will be granted. The requested scope will be provided by the connecting client as part of its authorization request, but may be pruned by the user in a confirmation dialog before being sent to this endpoint."}}},"Model76":{"type":"object","properties":{"client_id":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application)","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16}},"client_secret":{"type":"string","description":"The OAuth client secret for the requesting client application. Required for confidential clients, forbidden for public clients.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},"token":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64},"x-alternatives":[{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64},"x-alternatives":[{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},{"type":"string","maxLength":2048,"pattern":"^([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)$"}]},{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}}]},"token_type_hint":{"type":"string","description":"A hint as to what type of token is being revoked. Expected values are \"access_token\" or \"refresh_token\", Unrecognized values will be silently ignored, and specifying an incorrect hint may cause to the request to take longer but will still result in the token being destroyed.","maxLength":64}},"required":["client_id"]},"Model77":{"type":"object","properties":{"client_id":{"type":"string"},"id_token":{"type":"string"},"expiry_grace_period":{"type":"number","default":0}},"required":["client_id","id_token"]},"Model78":{"type":"array","items":{"type":"string"}},"Model79":{"type":"object","properties":{"acr":{"type":"string"},"aud":{"type":"string"},"alg":{"type":"string"},"at_hash":{"type":"string"},"amr":{"$ref":"#/definitions/Model78"},"exp":{"type":"number"},"fxa-aal":{"type":"number"},"iat":{"type":"number"},"iss":{"type":"string"},"sub":{"type":"string"}}},"Model80":{"type":"string","description":"The type of grant flow being used. If not specified, it will default to fxa-credentials unless a code parameter is provided, in which case it will default to authorization_code. The value of this parameter determines which other parameters will be expected in the request body, as follows:\n- When `grant_type=authorization_code`:\n  - `code`:  *validators.authorizationCode, required* The authorization code previously obtained through a redirect-based OAuth flow.\n  - `code_verifier`: *validators.pkceCodeVerifier, optional* The [**PKCE**](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/fxa-oauth-server/docs/pkce.md) code verifier used when obtaining code. This is required for public OAuth clients, who must authenticate their authorization code use via PKCE.\n  - `redirect_uri`: *string, URI, optional* The URI at which the client received the authorization code. If supplied this must match the value provided during OAuth client registration.\n- When `grant_type=refresh_token`:\n  - `refresh_token`: *validators.refreshToken, required* A refresh token, as issued by a previous call to this endpoint.\n  - `scope`: *string, optional* A space-separated list of scope values that will be held by the generated token. These must be a subset of the scopes originally granted when the refresh token was generated.\n- When `grant_type=fxa-credentials`:\n  - `scope`: *string, optional* A space-separated list of scope values that will be held by the generated tokens.\n  - `access_type`: *string, valid(online, offline), optional* If specified, a value of offline will cause the client to be granted a refresh token alongside its access token.\n-In addition, the request must be authenticated with a sessionToken.","default":"authorization_code","enum":["authorization_code"]},"Model81":{"type":"object","properties":{"grant_type":{"$ref":"#/definitions/Model80"},"client_id":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application)","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16}},"client_secret":{"type":"string","description":"The OAuth client secret for the requesting client application. Required for confidential clients, forbidden for public clients.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},"code":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"code_verifier":{"type":"string","minLength":43,"maxLength":128,"pattern":"^[A-Za-z0-9-\\._~]{43,128}$"},"redirect_uri":{"type":"string","x-format":{"uri":true}},"ttl":{"type":"number","description":"The desired lifetime of the issued access token, in seconds. The actual lifetime may be smaller than requested depending on server configuration, and will be returned in the `expired_in` property of the response.","x-constraint":{"sign":"positive"}},"ppid_seed":{"type":"integer","description":"Seed used in `sub` claim generation of JWT access tokens/ID tokens for clients with [Pseudonymous Pairwise Identifiers (PPID)](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/docs/oauth/pairwise-pseudonymous-identifiers.md) enabled. Used to forcibly rotate the `sub` claim. Must be an integer in the range 0-1024. If not specified, it will default to `0`.","default":0,"minimum":0,"maximum":1024},"resource":{"type":"string","description":"Indicates the target service or resource at which access is being requested. Its value must be an absolute URI, and may include a query component but must not include a fragment component. Added to the `aud` claim of JWT access tokens.","pattern":"#","x-format":{"uri":true}},"exclude_dau":{"type":"boolean","description":"When true, tag this access-token creation so it is excluded from the daily\nactive users (DAU) signal. The `access_token.created` Glean event still fires,\nwith its `exclude_dau` field set to true. Use this when the access token does\nnot represent active use of the service — for example, a token created for a\nsigned-in user regardless of whether they are using the service. Accepted on\nthe `fxa-credentials` and `authorization_code` grants.","default":false}},"required":["client_id","code"]},"Model82":{"type":"object","properties":{"access_token":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64},"x-alternatives":[{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},{"type":"string","maxLength":2048,"pattern":"^([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)$"}]},"refresh_token":{"type":"string","description":"A token that can be used to grant a new access token when the current one expires, via `grant_type=refresh_token` on this endpoint.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"id_token":{"type":"string","description":"OpenID Connect identity token, provisioned if the authorization was requested with `openid` scope.","minLength":50,"maxLength":10240,"pattern":"^[a-zA-Z0-9_\\-\\.~=]+$"},"session_token":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"scope":{"type":"string","description":"A space-separated list of scope values that the user has authorized, or is held by the granted access token that the connecting client will be granted. The requested scope will be provided by the connecting client as part of its authorization request, but may be pruned by the user in a confirmation dialog before being sent to this endpoint."},"token_type":{"$ref":"#/definitions/token_type"},"expires_in":{"type":"number","description":"The number of seconds until the access token will expire."},"auth_at":{"type":"number","description":"The UTC unix timestamp for the session at which the user last authenticated to FxA server when generating this token, in seconds since the epoch."},"keys_jwe":{"type":"string","maxLength":1024,"pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$"}},"required":["access_token","scope","token_type","expires_in","auth_at"]},"Model83":{"type":"object","properties":{"credentialId":{"type":"string","maxLength":1364,"pattern":"^[A-Za-z0-9_-]+$"},"pkR":{"type":"string","maxLength":178,"pattern":"^[A-Za-z0-9_-]+$","x-constraint":{"length":178}},"prfWrappedSkR":{"type":"string","maxLength":110,"pattern":"^[A-Za-z0-9_-]+$","x-constraint":{"length":110}},"keyWrapIv":{"type":"string","maxLength":16,"pattern":"^[A-Za-z0-9_-]+$","x-constraint":{"length":16}},"hpkeEncapsulatedSecret":{"type":"string","maxLength":178,"pattern":"^[A-Za-z0-9_-]+$","x-constraint":{"length":178}},"hpkeSealedKb":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_-]+$","x-constraint":{"length":64}}},"required":["credentialId","pkR","prfWrappedSkR","keyWrapIv","hpkeEncapsulatedSecret","hpkeSealedKb"]},"Model84":{"type":"object","properties":{"created":{"type":"boolean"}},"required":["created"]},"Model85":{"type":"object","properties":{"authPW":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"authPWVersion2":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string using the version 2 key stretching.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"wrapKb":{"type":"string","description":"The new `wrapKb` value as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"wrapKbVersion2":{"type":"string","description":"The new `wrapKb` value for authPW2 as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"clientSalt":{"type":"string","description":"The salt used when creating authPW. If not provided, it will be assumed that version one of the password encryption scheme was used.","pattern":"^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretch:|^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretchV2:"}},"required":["authPW"]},"Model86":{"type":"object"},"Model87":{"type":"object","properties":{"exists":{"type":"boolean"},"hint":{"type":"string"},"estimatedSyncDeviceCount":{"type":"number"}},"required":["exists"]},"Model88":{"type":"object","properties":{"hint":{"type":"string","description":"A string containing a user-defined hint to help them remember where they stored their account recovery key.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"}}},"Model89":{"type":"object","properties":{"recoveryKeyId":{"type":"string","maxLength":32,"pattern":"^(?:[a-fA-F0-9]{2})+$"}}},"type":{"type":"string","enum":["upgradeSession"],"maxLength":32,"x-format":{"alphanum":true}},"Model90":{"type":"object","properties":{"email":{"type":"string","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"service":{"type":"string","description":"Opaque alphanumeric token to be included in verification links.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"redirectTo":{"type":"string","maxLength":2048},"resume":{"type":"string","description":"Opaque URL-encoded string to be included in the verification link as a query parameter.","maxLength":2048},"style":{"$ref":"#/definitions/style"},"type":{"$ref":"#/definitions/type"}}},"Model91":{"type":"string","enum":["firefox-accounts-journey","knowledge-is-power","mozilla-foundation","take-action-for-the-internet","test-pilot","mozilla-and-you","security-privacy-news","mozilla-accounts","hubs","mdnplus"]},"Model92":{"type":"array","items":{"$ref":"#/definitions/Model91"}},"Model93":{"type":"object","properties":{"uid":{"type":"string","maxLength":32,"pattern":"^(?:[a-fA-F0-9]{2})+$"},"code":{"type":"string","minLength":32,"maxLength":32,"pattern":"^(?:[a-fA-F0-9]{2})+$"},"service":{"type":"string","description":"Opaque alphanumeric token to be included in verification links.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"reminder":{"type":"string","description":"Indicates that verification originates from a reminder email.","pattern":"^(?:first|second|final)$"},"type":{"type":"string","description":"The type of code being verified.","maxLength":32,"x-format":{"alphanum":true}},"style":{"$ref":"#/definitions/style"},"marketingOptIn":{"type":"boolean"},"newsletters":{"$ref":"#/definitions/Model92"}},"required":["uid","code"]},"Model94":{"type":"object","properties":{"code":{"type":"string","minLength":6,"maxLength":8}}},"Model95":{"type":"object","properties":{"phoneNumber":{"type":"string","pattern":"^\\+[1-9]\\d{1,14}$"}},"required":["phoneNumber"]},"Model96":{"type":"object","properties":{"customSessionTokenHandle":{"type":"string","description":"Opaque handle (from the sessions list) of the session token to destroy.","minLength":64,"maxLength":64,"pattern":"^(?:[a-fA-F0-9]{2})+$"}}},"Model97":{"type":"object","properties":{"reason":{"type":"string","maxLength":16}}},"Model98":{"type":"object","properties":{"uid":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"sessionToken":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"authAt":{"type":"integer"},"emailVerified":{"type":"boolean"},"sessionVerified":{"type":"boolean"},"verificationMethod":{"type":"string"},"verificationReason":{"type":"string"},"verified":{"type":"boolean"}},"required":["uid","sessionToken"]},"Model99":{"type":"string","enum":["email","email-otp","email-2fa","email-captcha","totp-2fa"]},"Model100":{"type":"object","properties":{"email":{"type":"string","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"authPW":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"service":{"type":"string","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"redirectTo":{"type":"string","maxLength":2048},"resume":{"type":"string"},"reason":{"type":"string","maxLength":16},"unblockCode":{"type":"string","pattern":"^[a-zA-Z0-9]*$","x-constraint":{"length":8}},"metricsContext":{"$ref":"#/definitions/metricsContext"},"originalLoginEmail":{"type":"string","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"verificationMethod":{"$ref":"#/definitions/Model99"},"sendSigninVerificationEmail":{"type":"boolean"}},"required":["email","authPW"]},"Model101":{"type":"object","properties":{"uid":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"keyFetchToken":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"verificationMethod":{"type":"string"},"verificationReason":{"type":"string"},"emailVerified":{"type":"boolean"},"sessionVerified":{"type":"boolean"},"authAt":{"type":"integer"},"metricsEnabled":{"type":"boolean"},"verified":{"type":"boolean"}},"required":["uid","emailVerified","sessionVerified","metricsEnabled","verified"]},"scopes":{"type":"array","items":{"type":"string","maxLength":256,"pattern":"^[a-zA-Z0-9 _\\/.:-]*$"}},"Model102":{"type":"string","enum":["firefox-accounts-journey","knowledge-is-power","mozilla-foundation","take-action-for-the-internet","test-pilot","mozilla-and-you","security-privacy-news","mozilla-accounts","hubs","mdnplus"]},"Model103":{"type":"array","items":{"$ref":"#/definitions/Model102"}},"Model104":{"type":"object","properties":{"code":{"type":"string","pattern":"^[0-9]+$"},"service":{"type":"string","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"scopes":{"$ref":"#/definitions/scopes"},"marketingOptIn":{"type":"boolean"},"newsletters":{"$ref":"#/definitions/Model103"},"metricsContext":{"$ref":"#/definitions/metricsContext"}}},"Model105":{"type":"object","properties":{"email":{"type":"string","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"productName":{"type":"string"},"productPlatform":{"type":"string"},"productVersion":{"type":"string"},"topic":{"type":"string"},"app":{"type":"string"},"subject":{"type":"string"},"message":{"type":"string"},"product":{"type":"string"},"category":{"type":"string"},"brand_id":{"type":"integer"}},"required":["productName","topic","message"]},"Model106":{"type":"object","properties":{"success":{"type":"boolean"},"ticket":{"type":"number"},"error":{"type":"string"}},"required":["success"]},"Model107":{"type":"object","properties":{"code":{"type":"string","description":"The TOTP code to check","maxLength":32,"pattern":"^[0-9]+$"}},"required":["code"]},"Model108":{"type":"object","properties":{"success":{"type":"boolean"}}},"Model109":{"type":"object","properties":{"clientId":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":16}},"sessionTokenHandle":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$"},"refreshTokenId":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"deviceId":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":32}}}},"Model110":{"type":"object"},"Model111":{"type":"object","properties":{"email":{"type":"string","description":"The primary email for this account.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"}}},"currentVersion":{"type":"string","enum":["v1","v2"]},"Model112":{"type":"object","properties":{"currentVersion":{"$ref":"#/definitions/currentVersion"},"clientSalt":{"type":"string","pattern":"^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretch:|^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretchV2:"},"upgradeNeeded":{"type":"boolean"}}},"Model113":{"type":"object","properties":{"id":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":32}}},"required":["id"]},"Model114":{"type":"object"},"Model115":{"type":"object","description":"Opaque payload to be forwarded to the device."},"Model116":{"type":"object","properties":{"target":{"type":"string","description":"The id of the device on which to invoke the command.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":32}},"command":{"type":"string","description":"The id of the command to be invoked, as found in the device's availableCommands set."},"payload":{"$ref":"#/definitions/Model115"},"ttl":{"type":"integer","description":"The time in milliseconds after which the command should expire, if not processed by the device.","minimum":0,"maximum":10000000}},"required":["target","command","payload"]},"Model117":{"type":"object","properties":{"enqueued":{"type":"boolean"},"notified":{"type":"boolean"},"notifyError":{"type":"string"}}},"to":{"type":"string","description":"Devices to notify. String `'all'` or an array containing the relevant device ids.","enum":["all"]},"_endpointAction":{"type":"string","enum":["accountVerify"]},"excluded":{"type":"array","description":"Array of device ids to exclude from the notification. Ignored unless `to:\"all\"` is specified.","items":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":32}}},"Model118":{"type":"object","description":"Push payload, validated against [**pushpayloads.schema.json**](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/lib/pushpayloads.schema.json)."},"Model119":{"type":"object","properties":{"to":{"$ref":"#/definitions/to"},"_endpointAction":{"$ref":"#/definitions/_endpointAction"},"excluded":{"$ref":"#/definitions/excluded"},"payload":{"$ref":"#/definitions/Model118"},"TTL":{"type":"integer","description":"Push notification TTL, defaults to `0`.","minimum":0}},"required":["to","payload"]},"Model120":{"type":"object"},"Model121":{"type":"object","properties":{"uid":{"type":"string","description":"The user id.","maxLength":32,"pattern":"^(?:[a-fA-F0-9]{2})+$"},"unblockCode":{"type":"string","description":"Alphanumeric code used to unblock certain rate-limitings.","pattern":"^[a-zA-Z0-9]*$","x-constraint":{"length":8}}},"required":["uid","unblockCode"]},"Model122":{"type":"object","properties":{"email":{"type":"string","description":"The primary email for this account.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"metricsContext":{"$ref":"#/definitions/metricsContext"}},"required":["email"]},"Model123":{"type":"object","properties":{"email":{"type":"string","description":"The primary email for this account.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"code":{"type":"string","description":"The OTP code sent to the user email","pattern":"^[0-9]+$","x-constraint":{"length":6}},"clientId":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application)","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":16}},"service":{"type":"string","description":"Opaque alphanumeric token to be included in verification links.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"metricsContext":{"$ref":"#/definitions/metricsContext"}},"required":["email","code"]},"Model124":{"type":"string","enum":["totp-2fa"]},"verificationReason":{"type":"string","enum":["login"]},"Model125":{"type":"object","properties":{"uid":{"type":"string"},"sessionToken":{"type":"string"},"verified":{"type":"boolean"},"authAt":{"type":"number"},"isNewAccount":{"type":"boolean"},"verificationMethod":{"$ref":"#/definitions/Model124"},"verificationReason":{"$ref":"#/definitions/verificationReason"}},"required":["uid","sessionToken","verified","authAt","isNewAccount"]},"Model126":{"type":"object","properties":{"email":{"type":"string","description":"The primary email for this account.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"clientId":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application)","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":16}},"service":{"type":"string","description":"Opaque alphanumeric token to be included in verification links.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"metricsContext":{"$ref":"#/definitions/metricsContext"}},"required":["email"]},"Model127":{"type":"object"},"Model128":{"type":"object","properties":{"email":{"type":"string","description":"The primary email for this account.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"clientId":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application)","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":16}},"service":{"type":"string","description":"Opaque alphanumeric token to be included in verification links.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"metricsContext":{"$ref":"#/definitions/metricsContext"}},"required":["email"]},"Model129":{"type":"object"},"Model130":{"type":"object","properties":{"email":{"type":"string","description":"The primary email for this account.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"oldAuthPW":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"authPW":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"authPWVersion2":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"wrapKb":{"type":"string","description":"The new `wrapKb` value as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"wrapKbVersion2":{"type":"string","description":"The new `wrapKb` value for authPW2 as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"clientSalt":{"type":"string","description":"The salt used when creating authPW. If not provided, it will be assumed that version one of the password encryption scheme was used.","pattern":"^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretch:|^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretchV2:"}},"required":["oldAuthPW","authPW"]},"Model131":{"type":"object","properties":{"authPW":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"authPWVersion2":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string using the version 2 key stretching.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"wrapKb":{"type":"string","description":"The new `wrapKb` value as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"wrapKbVersion2":{"type":"string","description":"The new `wrapKb` value for authPW2 as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"clientSalt":{"type":"string","description":"The salt used when creating authPW. If not provided, it will be assumed that version one of the password encryption scheme was used.","pattern":"^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretch:|^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretchV2:"}},"required":["authPW"]},"Model132":{"type":"object","properties":{"email":{"type":"string","description":"The email address to delete.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"}},"required":["email"]},"Model133":{"type":"object","properties":{"email":{"type":"string","description":"The new primary email address of the user.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"}},"required":["email"]},"Model134":{"type":"object","properties":{"code":{"type":"string","minLength":6,"maxLength":8}}},"Model135":{"type":"object","properties":{"phoneNumber":{"type":"string","pattern":"^\\+[1-9]\\d{1,14}$"}},"required":["phoneNumber"]},"Model136":{"type":"object","properties":{"metricsContext":{"$ref":"#/definitions/metricsContext"}}},"Model137":{"type":"object","properties":{"qrCodeUrl":{"type":"string"},"secret":{"type":"string"}},"required":["qrCodeUrl","secret"]},"Model138":{"type":"string","enum":["public-key"]},"response":{"type":"object","properties":{"clientDataJSON":{"type":"string","maxLength":2048,"pattern":"^[A-Za-z0-9_-]+$"},"authenticatorData":{"type":"string","maxLength":16384,"pattern":"^[A-Za-z0-9_-]+$"},"signature":{"type":"string","maxLength":1024,"pattern":"^[A-Za-z0-9_-]+$"},"userHandle":{"type":"string","maxLength":128,"pattern":"^[A-Za-z0-9_-]+$"}},"required":["clientDataJSON","authenticatorData","signature"]},"Model139":{"type":"object","properties":{"id":{"type":"string","maxLength":1364,"pattern":"^[A-Za-z0-9_-]+$"},"rawId":{"type":"string","maxLength":1364,"pattern":"^[A-Za-z0-9_-]+$"},"type":{"$ref":"#/definitions/Model138"},"response":{"$ref":"#/definitions/response"}},"required":["id","type","response"]},"Model140":{"type":"object","properties":{"response":{"$ref":"#/definitions/Model139"},"challenge":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_-]+$"},"service":{"type":"string","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"keysRequired":{"type":"boolean"},"prfSupported":{"type":"boolean"},"metricsContext":{"$ref":"#/definitions/metricsContext"}},"required":["response","challenge","keysRequired"]},"Model141":{"type":"object","properties":{"uid":{"type":"string"},"sessionToken":{"type":"string"},"verified":{"type":"boolean"},"hasPassword":{"type":"boolean"},"mfaToken":{"type":"string"}},"required":["uid","sessionToken","verified","hasPassword"]},"Model142":{"type":"string","enum":["2fa","email","recovery_key","password","passkey"]},"Model143":{"type":"object","properties":{"keysRequired":{"type":"boolean"},"scope":{"$ref":"#/definitions/Model142"}}},"Model144":{"type":"object"},"allowCredentials":{"type":"array","items":{"$ref":"#/definitions/Model144"}},"userVerification":{"type":"string","enum":["required"]},"Model145":{"type":"string","enum":["hybrid","security-key","client-device"]},"hints":{"type":"array","items":{"$ref":"#/definitions/Model145"}},"extensions":{"type":"object"},"Model146":{"type":"object","properties":{"challenge":{"type":"string"},"allowCredentials":{"$ref":"#/definitions/allowCredentials"},"timeout":{"type":"number"},"userVerification":{"$ref":"#/definitions/userVerification"},"rpId":{"type":"string"},"hints":{"$ref":"#/definitions/hints"},"extensions":{"$ref":"#/definitions/extensions"}},"required":["challenge","userVerification"]},"Model147":{"type":"string","enum":["public-key"]},"Model148":{"type":"object","properties":{"clientDataJSON":{"type":"string","maxLength":2048,"pattern":"^[A-Za-z0-9_-]+$"},"attestationObject":{"type":"string","maxLength":32768,"pattern":"^[A-Za-z0-9_-]+$"},"authenticatorData":{"type":"string","maxLength":16384,"pattern":"^[A-Za-z0-9_-]+$"},"publicKey":{"type":"string","maxLength":1024,"pattern":"^[A-Za-z0-9_-]+$"}},"required":["clientDataJSON","attestationObject"]},"prf":{"type":"object","properties":{"enabled":{"type":"boolean"}}},"clientExtensionResults":{"type":"object","properties":{"prf":{"$ref":"#/definitions/prf"}}},"Model149":{"type":"object","properties":{"id":{"type":"string","maxLength":1364,"pattern":"^[A-Za-z0-9_-]+$"},"rawId":{"type":"string","maxLength":1364,"pattern":"^[A-Za-z0-9_-]+$"},"type":{"$ref":"#/definitions/Model147"},"response":{"$ref":"#/definitions/Model148"},"authenticatorAttachment":{"type":"string"},"clientExtensionResults":{"$ref":"#/definitions/clientExtensionResults"}},"required":["id","type","response"]},"Model150":{"type":"object","properties":{"response":{"$ref":"#/definitions/Model149"},"challenge":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_-]+$"}},"required":["response","challenge"]},"rp":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}},"required":["name"]},"user":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"displayName":{"type":"string"}},"required":["id","name","displayName"]},"Model151":{"type":"string","enum":["public-key"]},"Model152":{"type":"object","properties":{"alg":{"type":"number"},"type":{"$ref":"#/definitions/Model151"}},"required":["alg","type"]},"pubKeyCredParams":{"type":"array","items":{"$ref":"#/definitions/Model152"}},"Model153":{"type":"string","enum":["public-key"]},"Model154":{"type":"object","properties":{"id":{"type":"string"},"type":{"$ref":"#/definitions/Model153"},"transports":{"$ref":"#/definitions/transports"}},"required":["id","type"]},"excludeCredentials":{"type":"array","items":{"$ref":"#/definitions/Model154"}},"authenticatorAttachment":{"type":"string","enum":["cross-platform","platform"]},"residentKey":{"type":"string","enum":["discouraged","preferred","required"]},"authenticatorSelection":{"type":"object","properties":{"authenticatorAttachment":{"$ref":"#/definitions/authenticatorAttachment"},"requireResidentKey":{"type":"boolean"},"residentKey":{"$ref":"#/definitions/residentKey"},"userVerification":{"$ref":"#/definitions/userVerification"}},"required":["userVerification"]},"Model155":{"type":"string","enum":["hybrid","security-key","client-device"]},"Model156":{"type":"array","items":{"$ref":"#/definitions/Model155"}},"attestation":{"type":"string","enum":["direct","enterprise","indirect","none"]},"Model157":{"type":"string","enum":["fido-u2f","packed","android-safetynet","android-key","tpm","apple","none"]},"attestationFormats":{"type":"array","items":{"$ref":"#/definitions/Model157"}},"eval":{"type":"object","properties":{"first":{"type":"string"},"second":{"type":"string"}},"required":["first"]},"Model158":{"type":"object","properties":{"eval":{"$ref":"#/definitions/eval"}}},"Model159":{"type":"object","properties":{"appid":{"type":"string"},"credProps":{"type":"boolean"},"hmacCreateSecret":{"type":"boolean"},"minPinLength":{"type":"boolean"},"prf":{"$ref":"#/definitions/Model158"}}},"Model160":{"type":"object","properties":{"rp":{"$ref":"#/definitions/rp"},"user":{"$ref":"#/definitions/user"},"challenge":{"type":"string"},"pubKeyCredParams":{"$ref":"#/definitions/pubKeyCredParams"},"timeout":{"type":"number"},"excludeCredentials":{"$ref":"#/definitions/excludeCredentials"},"authenticatorSelection":{"$ref":"#/definitions/authenticatorSelection"},"hints":{"$ref":"#/definitions/Model156"},"attestation":{"$ref":"#/definitions/attestation"},"attestationFormats":{"$ref":"#/definitions/attestationFormats"},"extensions":{"$ref":"#/definitions/Model159"}},"required":["rp","user","challenge","pubKeyCredParams"]},"Model161":{"type":"string","enum":["public-key"]},"Model162":{"type":"object","properties":{"id":{"type":"string","maxLength":1364,"pattern":"^[A-Za-z0-9_-]+$"},"rawId":{"type":"string","maxLength":1364,"pattern":"^[A-Za-z0-9_-]+$"},"type":{"$ref":"#/definitions/Model161"},"response":{"$ref":"#/definitions/response"}},"required":["id","type","response"]},"Model163":{"type":"object","properties":{"response":{"$ref":"#/definitions/Model162"},"challenge":{"type":"string","maxLength":64,"pattern":"^[A-Za-z0-9_-]+$"}},"required":["response","challenge"]},"Model164":{"type":"object","properties":{"mfaToken":{"type":"string"}},"required":["mfaToken"]},"Model165":{"type":"string","enum":["2fa","email","recovery_key","password","passkey"]},"Model166":{"type":"object","properties":{"scope":{"$ref":"#/definitions/Model165"},"credentialId":{"type":"string","maxLength":1364,"pattern":"^[A-Za-z0-9_-]+$"}},"required":["scope"]},"Model167":{"type":"string","enum":["hybrid","security-key","client-device"]},"Model168":{"type":"array","items":{"$ref":"#/definitions/Model167"}},"Model169":{"type":"object","properties":{"challenge":{"type":"string"},"allowCredentials":{"$ref":"#/definitions/allowCredentials"},"timeout":{"type":"number"},"userVerification":{"$ref":"#/definitions/userVerification"},"rpId":{"type":"string"},"hints":{"$ref":"#/definitions/Model168"},"extensions":{"$ref":"#/definitions/extensions"}},"required":["challenge","allowCredentials","userVerification"]},"Model170":{"type":"object","properties":{"authPW":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"authPWVersion2":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"wrapKb":{"type":"string","description":"The new `wrapKb` value as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"wrapKbVersion2":{"type":"string","description":"The new `wrapKb` value for authPW2 as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"clientSalt":{"type":"string","description":"The salt used when creating authPW. If not provided, it will be assumed that version one of the password encryption scheme was used.","pattern":"^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretch:|^identity\\.mozilla\\.com\\/picl\\/v1\\/quickStretchV2:"},"sessionToken":{"type":"string","description":"Indicates whether a new `sessionToken` is required, default to `false`.","minLength":64,"maxLength":64,"pattern":"^(?:[a-fA-F0-9]{2})+$"}},"required":["authPW","sessionToken"]},"Model171":{"type":"object","properties":{"email":{"type":"string","description":"The primary email for this account.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"oldAuthPW":{"type":"string","description":"The PBKDF2/HKDF-stretched password as a hex string.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}}},"required":["email","oldAuthPW"]},"Model172":{"type":"object","properties":{"email":{"type":"string","description":"Recovery email for the account.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"service":{"type":"string","description":"Identifies the relying service the user was interacting with that triggered the password reset.","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"metricsContext":{"$ref":"#/definitions/metricsContext"}},"required":["email"]},"Model173":{"type":"object","properties":{"code":{"type":"string","description":"The code sent to the user's recovery email.","minLength":32,"maxLength":32,"pattern":"^(?:[a-fA-F0-9]{2})+$"},"accountResetWithRecoveryKey":{"type":"boolean"},"includeRecoveryKeyPrompt":{"type":"boolean"}},"required":["code"]},"Model174":{"type":"object","properties":{"accountResetToken":{"type":"string"}}},"Model175":{"type":"object","properties":{"email":{"type":"string","description":"Recovery email for the account.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"code":{"type":"string","pattern":"^[0-9]+$","x-constraint":{"length":8}},"metricsContext":{"$ref":"#/definitions/metricsContext"}},"required":["email"]},"Model176":{"type":"object","properties":{"code":{"type":"string"},"emailToHashWith":{"type":"string"},"token":{"type":"string"},"uid":{"type":"string"},"hasPasskey":{"type":"boolean"},"hasPasskeyWraps":{"type":"boolean"}},"required":["code","emailToHashWith","token","uid"]},"Model177":{"type":"object","properties":{"code":{"type":"string","minLength":6,"maxLength":8}}},"Model178":{"type":"object","properties":{"code":{"type":"string","description":"The TOTP code to check","maxLength":32,"pattern":"^[0-9]+$"},"service":{"type":"string","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"metricsContext":{"$ref":"#/definitions/metricsContext"}},"required":["code"]},"Model179":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]},"Model180":{"type":"object","properties":{"code":{"type":"string","minLength":8,"maxLength":20,"pattern":"^[a-zA-Z0-9]*$"}}},"Model181":{"type":"object","properties":{"remaining":{"type":"number"}}},"Model182":{"type":"object","properties":{"email":{"type":"string","description":"The secondary email address to verify.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"}},"required":["email"]},"Model183":{"type":"object","properties":{"email":{"type":"string","description":"The secondary email address to verify.","maxLength":255,"pattern":"^(?:[^\\u0000-\\u001F\\u007F\\u0080-\\u009F\\u2028-\\u2029\\uD800-\\uDFFF\\uE000-\\uF8FF\\uFFF9-\\uFFFC\\uFFFE-\\uFFFF])*$"},"code":{"type":"string","description":"Time based code to verify secondary email","maxLength":32,"pattern":"^[0-9]+$"}},"required":["email","code"]},"Model184":{"type":"object","properties":{"code":{"type":"string","description":"The TOTP code to check","maxLength":32,"pattern":"^[0-9]+$"}},"required":["code"]},"Model185":{"type":"object","properties":{"success":{"type":"boolean"}}},"Model186":{"type":"object","properties":{"metricsContext":{"$ref":"#/definitions/metricsContext"}}},"Model187":{"type":"object","properties":{"qrCodeUrl":{"type":"string"},"secret":{"type":"string"}},"required":["qrCodeUrl","secret"]},"Model188":{"type":"object","properties":{"service":{"type":"string","maxLength":16,"pattern":"^[a-zA-Z0-9\\-]*$"},"metricsContext":{"$ref":"#/definitions/metricsContext"}}},"Model189":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]},"Model190":{"type":"object","properties":{"code":{"type":"string","description":"The TOTP code to check","maxLength":32,"pattern":"^[0-9]+$"},"metricsContext":{"$ref":"#/definitions/metricsContext"}},"required":["code"]},"Model191":{"type":"object","properties":{"success":{"type":"boolean"}},"required":["success"]},"Model192":{"type":"object","properties":{"signedPayload":{"type":"string"}},"required":["signedPayload"]},"message":{"type":"object","properties":{"data":{"type":"string"}},"required":["data"]},"Model193":{"type":"object","properties":{"message":{"$ref":"#/definitions/message"}},"required":["message"]},"Model194":{"type":"object","properties":{"originalTransactionId":{"type":"string"}},"required":["originalTransactionId"]},"Model195":{"type":"object","properties":{"sku":{"type":"string"},"token":{"type":"string"}},"required":["sku","token"]},"Model196":{"type":"object","properties":{"success":{"type":"boolean"}}},"Model197":{"type":"object","properties":{"success":{"type":"boolean"}}},"Model198":{"type":"object"},"Model199":{"type":"object","properties":{"deleted":{"type":"boolean"}},"required":["deleted"]},"Model200":{"type":"object","properties":{"name":{"type":"string","minLength":1,"maxLength":255}},"required":["name"]}},"x-alt-definitions":{"grant_type":{"type":"string","description":"The type of grant flow being used. If not specified, it will default to fxa-credentials unless a code parameter is provided, in which case it will default to authorization_code. The value of this parameter determines which other parameters will be expected in the request body, as follows:\n- When `grant_type=authorization_code`:\n  - `code`:  *validators.authorizationCode, required* The authorization code previously obtained through a redirect-based OAuth flow.\n  - `code_verifier`: *validators.pkceCodeVerifier, optional* The [**PKCE**](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/fxa-oauth-server/docs/pkce.md) code verifier used when obtaining code. This is required for public OAuth clients, who must authenticate their authorization code use via PKCE.\n  - `redirect_uri`: *string, URI, optional* The URI at which the client received the authorization code. If supplied this must match the value provided during OAuth client registration.\n- When `grant_type=refresh_token`:\n  - `refresh_token`: *validators.refreshToken, required* A refresh token, as issued by a previous call to this endpoint.\n  - `scope`: *string, optional* A space-separated list of scope values that will be held by the generated token. These must be a subset of the scopes originally granted when the refresh token was generated.\n- When `grant_type=fxa-credentials`:\n  - `scope`: *string, optional* A space-separated list of scope values that will be held by the generated tokens.\n  - `access_type`: *string, valid(online, offline), optional* If specified, a value of offline will cause the client to be granted a refresh token alongside its access token.\n-In addition, the request must be authenticated with a sessionToken.","default":"authorization_code","enum":["authorization_code"]},"Model1":{"type":"object","properties":{"grant_type":{"$ref":"#/x-alt-definitions/grant_type"},"client_id":{"type":"string","description":"The OAuth client identifier for the requesting client application (provided by the connecting client application)","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16}},"client_secret":{"type":"string","description":"The OAuth client secret for the requesting client application. Required for confidential clients, forbidden for public clients.","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},"code":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"code_verifier":{"type":"string","minLength":43,"maxLength":128,"pattern":"^[A-Za-z0-9-\\._~]{43,128}$"},"redirect_uri":{"type":"string","x-format":{"uri":true}},"ttl":{"type":"number","description":"The desired lifetime of the issued access token, in seconds. The actual lifetime may be smaller than requested depending on server configuration, and will be returned in the `expired_in` property of the response.","x-constraint":{"sign":"positive"}},"ppid_seed":{"type":"integer","description":"Seed used in `sub` claim generation of JWT access tokens/ID tokens for clients with [Pseudonymous Pairwise Identifiers (PPID)](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/docs/oauth/pairwise-pseudonymous-identifiers.md) enabled. Used to forcibly rotate the `sub` claim. Must be an integer in the range 0-1024. If not specified, it will default to `0`.","default":0,"minimum":0,"maximum":1024},"resource":{"type":"string","description":"Indicates the target service or resource at which access is being requested. Its value must be an absolute URI, and may include a query component but must not include a fragment component. Added to the `aud` claim of JWT access tokens.","pattern":"#","x-format":{"uri":true}},"exclude_dau":{"type":"boolean","description":"When true, tag this access-token creation so it is excluded from the daily\nactive users (DAU) signal. The `access_token.created` Glean event still fires,\nwith its `exclude_dau` field set to true. Use this when the access token does\nnot represent active use of the service — for example, a token created for a\nsigned-in user regardless of whether they are using the service. Accepted on\nthe `fxa-credentials` and `authorization_code` grants.","default":false}},"required":["client_id","code"]},"Model2":{"type":"string","enum":["refresh_token"]},"Model3":{"type":"object","properties":{"grant_type":{"$ref":"#/x-alt-definitions/Model2"},"client_id":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16}},"client_secret":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},"refresh_token":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"scope":{"type":"string"},"ttl":{"type":"number","x-constraint":{"sign":"positive"}},"ppid_seed":{"type":"integer","default":0,"minimum":0,"maximum":1024},"resource":{"type":"string","pattern":"#","x-format":{"uri":true}}},"required":["grant_type","client_id","refresh_token"]},"Model4":{"type":"string","default":"fxa-credentials","enum":["fxa-credentials"]},"access_type":{"type":"string","default":"online","enum":["online","offline"]},"reason":{"type":"string","enum":["token_migration"]},"Model5":{"type":"object","properties":{"grant_type":{"$ref":"#/x-alt-definitions/Model4"},"client_id":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":16}},"scope":{"type":"string"},"access_type":{"$ref":"#/x-alt-definitions/access_type"},"exclude_dau":{"type":"boolean","description":"When true, tag this access-token creation so it is excluded from the daily\nactive users (DAU) signal. The `access_token.created` Glean event still fires,\nwith its `exclude_dau` field set to true. Use this when the access token does\nnot represent active use of the service — for example, a token created for a\nsigned-in user regardless of whether they are using the service. Accepted on\nthe `fxa-credentials` and `authorization_code` grants.","default":false},"ttl":{"type":"number","x-constraint":{"sign":"positive"}},"resource":{"type":"string","pattern":"#","x-format":{"uri":true}},"reason":{"$ref":"#/x-alt-definitions/reason"}},"required":["client_id"]},"Model6":{"type":"string","enum":["urn:ietf:params:oauth:grant-type:token-exchange"]},"subject_token_type":{"type":"string","enum":["urn:ietf:params:oauth:token-type:refresh_token"]},"Model7":{"type":"object","properties":{"grant_type":{"$ref":"#/x-alt-definitions/Model6"},"subject_token":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"subject_token_type":{"$ref":"#/x-alt-definitions/subject_token_type"},"scope":{"type":"string"}},"required":["grant_type","subject_token","subject_token_type","scope"]},"token_type":{"type":"string","description":"The type of token, which determines how the client should use it in subsequent requests. Currently only Bearer tokens are supported.","enum":["bearer"]},"Model8":{"type":"object","properties":{"access_token":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64},"x-alternatives":[{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},{"type":"string","maxLength":2048,"pattern":"^([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)$"}]},"refresh_token":{"type":"string","description":"A token that can be used to grant a new access token when the current one expires, via `grant_type=refresh_token` on this endpoint.","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"id_token":{"type":"string","description":"OpenID Connect identity token, provisioned if the authorization was requested with `openid` scope.","minLength":50,"maxLength":10240,"pattern":"^[a-zA-Z0-9_\\-\\.~=]+$"},"session_token":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"scope":{"type":"string","description":"A space-separated list of scope values that the user has authorized, or is held by the granted access token that the connecting client will be granted. The requested scope will be provided by the connecting client as part of its authorization request, but may be pruned by the user in a confirmation dialog before being sent to this endpoint."},"token_type":{"$ref":"#/x-alt-definitions/token_type"},"expires_in":{"type":"number","description":"The number of seconds until the access token will expire."},"auth_at":{"type":"number","description":"The UTC unix timestamp for the session at which the user last authenticated to FxA server when generating this token, in seconds since the epoch."},"keys_jwe":{"type":"string","maxLength":1024,"pattern":"^[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]*\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+\\.[A-Za-z0-9-_]+$"}},"required":["access_token","scope","token_type","expires_in","auth_at"]},"Model9":{"type":"string","enum":["bearer"]},"Model10":{"type":"object","properties":{"access_token":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64},"x-alternatives":[{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},{"type":"string","maxLength":2048,"pattern":"^([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)$"}]},"id_token":{"type":"string","minLength":50,"maxLength":10240,"pattern":"^[a-zA-Z0-9_\\-\\.~=]+$"},"scope":{"type":"string"},"token_type":{"$ref":"#/x-alt-definitions/Model9"},"expires_in":{"type":"number"}},"required":["access_token","scope","token_type","expires_in"]},"Model11":{"type":"string","enum":["bearer"]},"Model12":{"type":"object","properties":{"access_token":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64},"x-alternatives":[{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},{"type":"string","maxLength":2048,"pattern":"^([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)$"}]},"refresh_token":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"id_token":{"type":"string","minLength":50,"maxLength":10240,"pattern":"^[a-zA-Z0-9_\\-\\.~=]+$"},"scope":{"type":"string"},"auth_at":{"type":"number"},"token_type":{"$ref":"#/x-alt-definitions/Model11"},"expires_in":{"type":"number"}},"required":["access_token","scope","auth_at","token_type","expires_in"]},"Model13":{"type":"string","enum":["bearer"]},"Model14":{"type":"object","properties":{"access_token":{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64},"x-alternatives":[{"type":"string","pattern":"^(?:[0-9a-f]{2})+$","x-constraint":{"length":64}},{"type":"string","maxLength":2048,"pattern":"^([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)\\.([a-zA-Z0-9\\-_]+)$"}]},"refresh_token":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":64}},"scope":{"type":"string"},"token_type":{"$ref":"#/x-alt-definitions/Model13"},"expires_in":{"type":"number"}},"required":["access_token","refresh_token","scope","token_type","expires_in"]},"to":{"type":"string","description":"Devices to notify. String `'all'` or an array containing the relevant device ids.","enum":["all"]},"_endpointAction":{"type":"string","enum":["accountVerify"]},"excluded":{"type":"array","description":"Array of device ids to exclude from the notification. Ignored unless `to:\"all\"` is specified.","items":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":32}}},"payload":{"type":"object","description":"Push payload, validated against [**pushpayloads.schema.json**](https://github.com/mozilla/fxa/blob/main/packages/fxa-auth-server/lib/pushpayloads.schema.json)."},"Model15":{"type":"object","properties":{"to":{"$ref":"#/x-alt-definitions/to"},"_endpointAction":{"$ref":"#/x-alt-definitions/_endpointAction"},"excluded":{"$ref":"#/x-alt-definitions/excluded"},"payload":{"$ref":"#/x-alt-definitions/payload"},"TTL":{"type":"integer","description":"Push notification TTL, defaults to `0`.","minimum":0}},"required":["to","payload"]},"Model16":{"type":"array","items":{"type":"string","pattern":"^(?:[a-fA-F0-9]{2})+$","x-constraint":{"length":32}}},"Model17":{"type":"object"},"Model18":{"type":"object","properties":{"to":{"$ref":"#/x-alt-definitions/Model16"},"_endpointAction":{"$ref":"#/x-alt-definitions/_endpointAction"},"payload":{"$ref":"#/x-alt-definitions/Model17"},"TTL":{"type":"integer","minimum":0}},"required":["to","payload"]}}}