Firefox Accounts API Documentation (0.0.1)
Download OpenAPI specification:Download
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. For a reference client implementation, see fxa-auth-client.
URL Structure for Auth Server
All requests use URLs of the form:
https://<base-URI>/v1/<endpoint-path>
Note that:
- All API access must be over a properly-validated HTTPS connection.
- The URL embeds a version identifier
v1
. Future revisions of this API may introduce new version numbers. - The base URI of the server may be configured on a per-client basis:
- The canonical URL for Mozilla's hosted Firefox Accounts server
is
https://api.accounts.firefox.com/v1
.
- The canonical URL for Mozilla's hosted Firefox Accounts server
is
Request Format
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.
The following request headers may be specified to influence the behavior of the server:
Accept-Language
may be used to localize emails and SMS messages.
Response format
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.
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.
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.
To simplify error handling for the client, the type of error is indicated by both
a defined HTTP status code and an application-specific errno
in the body.
For example:
{
"code": 400, // Matches the HTTP status code
"errno": 107, // Stable application-level error number
"error": "Bad Request", // String description of the error type
"message": "Invalid parameter in request body", // Specific error message
"info": "https://docs.dev.lcip.og/errors/1234" // Link to more information
}
Responses for some errors may include additional parameters.
Defined errors
The currently-defined values for code
and errno
are:
status code | errno | description |
---|---|---|
400 | 100 | Incorrect Database Patch Level |
400 | 101 | Account already exists |
400 | 102 | Unknown account |
400 | 103 | Incorrect password |
400 | 104 | Unconfirmed account |
400 | 105 | Invalid confirmation code |
400 | 106 | Invalid JSON in request body |
400 | 107 | Invalid parameter in request body |
400 | 108 | Missing parameter in request body |
401 | 109 | Invalid request signature |
401 | 110 | Invalid authentication token in request signature |
401 | 111 | Invalid timestamp in request signature |
411 | 112 | Missing content-length header |
413 | 113 | Request body too large |
429 | 114 | Client has sent too many requests |
401 | 115 | Invalid nonce in request signature |
410 | 116 | This endpoint is no longer supported |
400 | 120 | Incorrect email case |
400 | 123 | Unknown device |
400 | 124 | Session already registered by another device |
400 | 125 | The request was blocked for security reasons |
400 | 126 | Account must be reset |
400 | 127 | Invalid unblock code |
400 | 129 | Invalid phone number |
400 | 130 | Invalid region |
400 | 131 | Invalid message id |
500 | 132 | Message rejected |
400 | 133 | Email account sent complaint |
400 | 134 | Email account hard bounced |
400 | 135 | Email account soft bounced |
400 | 136 | Email already exists |
400 | 137 | Can not delete primary email |
400 | 138 | Unverified session |
400 | 139 | Can not add secondary email that is same as your primary |
400 | 140 | Email already exists |
400 | 141 | Email already exists |
400 | 142 | Sign in with this email type is not currently supported |
400 | 143 | Unknown email |
400 | 144 | Email already exists |
400 | 145 | Reset password with this email type is not currently supported |
400 | 146 | Invalid signin code |
400 | 147 | Can not change primary email to an unverified email |
400 | 148 | Can not change primary email to an email that does not belong to this account |
400 | 149 | This email can not currently be used to login |
400 | 150 | Can not resend email code to an email that does not belong to this account |
500 | 151 | Failed to send email |
422 | 151 | Failed to send email |
400 | 152 | Invalid token confirmation code |
400 | 153 | Expired token confirmation code |
400 | 154 | TOTP token already exists for this account. |
400 | 155 | TOTP token not found. |
400 | 156 | Backup authentication code not found. |
400 | 157 | Unavailable device command. |
400 | 158 | Account recovery key not found. |
400 | 159 | Account recovery key is not valid. |
400 | 160 | This request requires two step authentication enabled on your account. |
400 | 161 | Account recovery key already exists. |
400 | 162 | Unknown client_id |
400 | 164 | Stale auth timestamp |
409 | 165 | Redis WATCH detected a conflicting update |
400 | 166 | Not a public client |
400 | 167 | Incorrect redirect URI |
400 | 168 | Invalid response_type |
400 | 169 | Public clients require PKCE OAuth parameters |
400 | 170 | Required Authentication Context Reference values could not be satisfied |
400 | 171 | Incorrect client_secret |
400 | 172 | Unknown authorization code |
400 | 173 | Mismatched authorization code |
400 | 174 | Expired authorization code |
400 | 175 | Public clients require PKCE OAuth parameters |
404 | 176 | Unknown customer |
404 | 177 | Unknown subscription |
400 | 178 | Unknown subscription plan |
400 | 179 | Subscription payment token rejected |
400 | 180 | Subscription has already been cancelled |
400 | 181 | Customer update rejected |
400 | 182 | Unknown refresh token |
400 | 183 | Invalid or expired confirmation code |
400 | 184 | Subscription has already been cancelled |
400 | 185 | Subscription plan is not a valid update |
400 | 186 | Payment method failed |
409 | 187 | User already subscribed |
500 | 188 | Failed to find a subscription associated with Stripe source |
400 | 192 | Billing agreement already on file for this customer |
400 | 193 | PayPal payment token is missing |
400 | 194 | PayPal billing agreement is missing for the existing subscriber |
400 | 195 | Account for this email has an active subscription |
400 | 196 | Invalid token |
500 | 197 | IAP Internal Error |
404 | 198 | Unknown app name |
400 | 199 | Invalid promotion code |
503 | 201 | Service unavailable |
503 | 202 | Feature not enabled |
500 | 203 | A backend service request failed. |
503 | 204 | This client has been temporarily disabled |
500 | 205 | Could not login with third party account, please try again later |
400 | 206 | Can not create password, password already set. |
400 | 207 | Account creation rejected. |
403 | 208 | Purchase has been registered to another user. |
500 | 998 | An internal validation check failed. |
The following errors include additional response properties:
errno | description |
---|---|
100 | level, levelRequired |
101 | |
102 | |
103 | |
105 | |
107 | validation |
108 | param |
111 | serverTime |
114 | retryAfter, retryAfterLocalized, verificationMethod, verificationReason |
120 | |
124 | deviceId |
125 | verificationMethod, verificationReason |
126 | |
130 | region |
132 | reason, reasonCode |
133 | bouncedAt |
134 | bouncedAt |
135 | bouncedAt |
152 | |
153 | |
162 | clientId |
164 | authAt |
167 | redirectUri |
169 | invalidScopes |
171 | foundValue |
201 | retryAfter |
202 | retryAfter |
203 | service, operation |
998 | op, data |
Responses from intermediary servers
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.
Common examples include:
413 Request Entity Too Large
: may be returned by an upstream proxy server.502 Gateway Timeout
: may be returned if a load-balancer can't connect to application servers.
Validation
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.
lib/routes/validators
HEX_STRING
:/^(?:[a-fA-F0-9]{2})+$/
BASE_36
:/^[a-zA-Z0-9]*$/
URL_SAFE_BASE_64
:/^[A-Za-z0-9_-]+$/
PKCE_CODE_VERIFIER
:/^[A-Za-z0-9-\._~]{43,128}$/
DISPLAY_SAFE_UNICODE
:/^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-\u2029\uD800-\uDFFF\uE000-\uF8FF\uFFF9-\uFFFF])*$/
DISPLAY_SAFE_UNICODE_WITH_NON_BMP
:/^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-\u2029\uE000-\uF8FF\uFFF9-\uFFFF])*$/
BEARER_AUTH_REGEX
:/^Bearer\s+([a-z0-9+\/]+)$/i
service
:string, max(16), regex(/^[a-zA-Z0-9\-]*$/)
hexString
:string, regex(/^(?:[a-fA-F0-9]{2})+$/)
clientId
:module.exports.hexString.length(16)
clientSecret
:module.exports.hexString
accessToken
:module.exports.hexString.length(64)
refreshToken
:module.exports.hexString.length(64)
authorizationCode
:module.exports.hexString.length(64)
scope
:string, max(256), regex(/^[a-zA-Z0-9 _\/.:-]*$/), allow('')
assertion
:string, min(50), max(10240), regex(/^[a-zA-Z0-9_\-\.~=]+$/)
pkceCodeChallengeMethod
:string, valid('S256')
pkceCodeChallenge
:string, length(43), regex(module, exports.URL_SAFE_BASE_64)
pkceCodeVerifier
:string, length(43), regex(module, exports.PKCE_CODE_VERIFIER)
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-_]+$/)
verificationMethod
:string, valid()
authPW
:string, length(64), regex(HEX_STRING), required
wrapKb
:string, length(64), regex(/^(?:[a-fA-F0-9]{2})+$/)
recoveryKeyId
:string, regex(HEX_STRING), max(32)
recoveryData
:string, regex(/[a-zA-Z0-9.]/), max(1024), required
E164_NUMBER
:/^\+[1-9]\d{1,14}$/
DIGITS
:/^[0-9]+$/
DEVICE_COMMAND_NAME
:/^[a-zA-Z0-9._\/\-:]{1,100}$/
IP_ADDRESS
:string, ip
lib/metrics/context
SCHEMA
: object({deviceId
: string, length(32), regex(HEX_STRING), optionalentrypoint
: ENTRYPOINT_SCHEMA.optionalentrypointExperiment
: ENTRYPOINT_SCHEMA.optionalentrypointVariation
: ENTRYPOINT_SCHEMA.optionalflowId
: string, length(64), regex(HEX_STRING), optionalflowBeginTime
: number, integer, positive, optionalutmCampaign
: UTM_CAMPAIGN_SCHEMA.optionalutmContent
: UTM_SCHEMA.optionalutmMedium
: UTM_SCHEMA.optionalutmSource
: UTM_SCHEMA.optionalutmTerm
: UTM_SCHEMA.optional }), unknown(false), and('flowId', 'flowBeginTime')
schema
: SCHEMA.optionalrequiredSchema
: SCHEMA.required
lib/features
schema
: array, items(string), optional
lib/devices
schema
: {id
: isA.string.length(32).regex(HEX_STRING)location
: isA.object({city
: isA.string.optional.allow(null)country
: isA.string.optional.allow(null)state
: isA.string.optional.allow(null)stateCode
: isA.string.optional.allow(null)- })
name
: isA.string.max(255).regex(DISPLAY_SAFE_UNICODE_WITH_NON_BMP)nameResponse
: isA.string.max(255).allow('')type
: isA.string.max(16)pushCallback
: validators.pushCallbackUrl({ scheme: 'https' }).regex(PUSH_SERVER_REGEX).max(255).allow('')pushPublicKey
: isA.string.max(88).regex(URL_SAFE_BASE_64).allow('')pushAuthKey
: isA.string.max(24).regex(URL_SAFE_BASE_64).allow('')pushEndpointExpired
: isA.boolean.strictavailableCommands
: isA.object.pattern(validators.DEVICE_COMMAND_NAME- `isA.string.max(2048))
}
Back-off protocol
During periods of heavy load, the server may request that clients enter a "back-off" state, in which they avoid making further requests.
At such times,
it will return a 503 Service Unavailable
response
with a Retry-After
header denoting the number of seconds to wait
before issuing any further requests.
It will also include errno: 201
and a retryAfter
field
matching the value of the Retry-After
header
in the body.
For example, the following response indicates that the client should suspend making further requests for 30 seconds:
HTTP/1.1 503 Service Unavailable
Retry-After: 30
Content-Type: application/json
{
"code": 503,
"errno": 201,
"error": "Service Unavailable",
"message": "Service unavailable",
"info": "https://mozilla.github.io/ecosystem-platform/api#section/Response-format",
"retryAfter": 30,
"retryAfterLocalized": "in a few seconds"
}
All requests use URLs of the form:
https://<base-URI>/v1/<endpoint-path>
Note that:
- All API access must be over a properly-validated HTTPS connection.
- The URL embeds a version identifier
v1
. Future revisions of this API may introduce new version numbers. - The base URI of the server may be configured on a per-client basis:
- The canonical URL for Mozilla's hosted Firefox Accounts server
is
https://api.accounts.firefox.com/v1
.
- The canonical URL for Mozilla's hosted Firefox Accounts server
is
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.
The following request headers may be specified to influence the behavior of the server:
Accept-Language
may be used to localize emails and SMS messages.
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.
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.
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.
To simplify error handling for the client, the type of error is indicated by both
a defined HTTP status code and an application-specific errno
in the body.
For example:
{
"code": 400, // Matches the HTTP status code
"errno": 107, // Stable application-level error number
"error": "Bad Request", // String description of the error type
"message": "Invalid parameter in request body", // Specific error message
"info": "https://docs.dev.lcip.og/errors/1234" // Link to more information
}
Responses for some errors may include additional parameters.
Defined errors
The currently-defined values for code
and errno
are:
status code | errno | description |
---|---|---|
400 | 100 | Incorrect Database Patch Level |
400 | 101 | Account already exists |
400 | 102 | Unknown account |
400 | 103 | Incorrect password |
400 | 104 | Unconfirmed account |
400 | 105 | Invalid confirmation code |
400 | 106 | Invalid JSON in request body |
400 | 107 | Invalid parameter in request body |
400 | 108 | Missing parameter in request body |
401 | 109 | Invalid request signature |
401 | 110 | Invalid authentication token in request signature |
401 | 111 | Invalid timestamp in request signature |
411 | 112 | Missing content-length header |
413 | 113 | Request body too large |
429 | 114 | Client has sent too many requests |
401 | 115 | Invalid nonce in request signature |
410 | 116 | This endpoint is no longer supported |
400 | 120 | Incorrect email case |
400 | 123 | Unknown device |
400 | 124 | Session already registered by another device |
400 | 125 | The request was blocked for security reasons |
400 | 126 | Account must be reset |
400 | 127 | Invalid unblock code |
400 | 129 | Invalid phone number |
400 | 130 | Invalid region |
400 | 131 | Invalid message id |
500 | 132 | Message rejected |
400 | 133 | Email account sent complaint |
400 | 134 | Email account hard bounced |
400 | 135 | Email account soft bounced |
400 | 136 | Email already exists |
400 | 137 | Can not delete primary email |
400 | 138 | Unverified session |
400 | 139 | Can not add secondary email that is same as your primary |
400 | 140 | Email already exists |
400 | 141 | Email already exists |
400 | 142 | Sign in with this email type is not currently supported |
400 | 143 | Unknown email |
400 | 144 | Email already exists |
400 | 145 | Reset password with this email type is not currently supported |
400 | 146 | Invalid signin code |
400 | 147 | Can not change primary email to an unverified email |
400 | 148 | Can not change primary email to an email that does not belong to this account |
400 | 149 | This email can not currently be used to login |
400 | 150 | Can not resend email code to an email that does not belong to this account |
500 | 151 | Failed to send email |
422 | 151 | Failed to send email |
400 | 152 | Invalid token confirmation code |
400 | 153 | Expired token confirmation code |
400 | 154 | TOTP token already exists for this account. |
400 | 155 | TOTP token not found. |
400 | 156 | Backup authentication code not found. |
400 | 157 | Unavailable device command. |
400 | 158 | Account recovery key not found. |
400 | 159 | Account recovery key is not valid. |
400 | 160 | This request requires two step authentication enabled on your account. |
400 | 161 | Account recovery key already exists. |
400 | 162 | Unknown client_id |
400 | 164 | Stale auth timestamp |
409 | 165 | Redis WATCH detected a conflicting update |
400 | 166 | Not a public client |
400 | 167 | Incorrect redirect URI |
400 | 168 | Invalid response_type |
400 | 169 | Public clients require PKCE OAuth parameters |
400 | 170 | Required Authentication Context Reference values could not be satisfied |
400 | 171 | Incorrect client_secret |
400 | 172 | Unknown authorization code |
400 | 173 | Mismatched authorization code |
400 | 174 | Expired authorization code |
400 | 175 | Public clients require PKCE OAuth parameters |
404 | 176 | Unknown customer |
404 | 177 | Unknown subscription |
400 | 178 | Unknown subscription plan |
400 | 179 | Subscription payment token rejected |
400 | 180 | Subscription has already been cancelled |
400 | 181 | Customer update rejected |
400 | 182 | Unknown refresh token |
400 | 183 | Invalid or expired confirmation code |
400 | 184 | Subscription has already been cancelled |
400 | 185 | Subscription plan is not a valid update |
400 | 186 | Payment method failed |
409 | 187 | User already subscribed |
500 | 188 | Failed to find a subscription associated with Stripe source |
400 | 192 | Billing agreement already on file for this customer |
400 | 193 | PayPal payment token is missing |
400 | 194 | PayPal billing agreement is missing for the existing subscriber |
400 | 195 | Account for this email has an active subscription |
400 | 196 | Invalid token |
500 | 197 | IAP Internal Error |
404 | 198 | Unknown app name |
400 | 199 | Invalid promotion code |
503 | 201 | Service unavailable |
503 | 202 | Feature not enabled |
500 | 203 | A backend service request failed. |
503 | 204 | This client has been temporarily disabled |
500 | 205 | Could not login with third party account, please try again later |
400 | 206 | Can not create password, password already set. |
400 | 207 | Account creation rejected. |
403 | 208 | Purchase has been registered to another user. |
500 | 998 | An internal validation check failed. |
The following errors include additional response properties:
errno | description |
---|---|
100 | level, levelRequired |
101 | |
102 | |
103 | |
105 | |
107 | validation |
108 | param |
111 | serverTime |
114 | retryAfter, retryAfterLocalized, verificationMethod, verificationReason |
120 | |
124 | deviceId |
125 | verificationMethod, verificationReason |
126 | |
130 | region |
132 | reason, reasonCode |
133 | bouncedAt |
134 | bouncedAt |
135 | bouncedAt |
152 | |
153 | |
162 | clientId |
164 | authAt |
167 | redirectUri |
169 | invalidScopes |
171 | foundValue |
201 | retryAfter |
202 | retryAfter |
203 | service, operation |
998 | op, data |
Responses from intermediary servers
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.
Common examples include:
413 Request Entity Too Large
: may be returned by an upstream proxy server.502 Gateway Timeout
: may be returned if a load-balancer can't connect to application servers.
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.
lib/routes/validators
HEX_STRING
:/^(?:[a-fA-F0-9]{2})+$/
BASE_36
:/^[a-zA-Z0-9]*$/
URL_SAFE_BASE_64
:/^[A-Za-z0-9_-]+$/
PKCE_CODE_VERIFIER
:/^[A-Za-z0-9-\._~]{43,128}$/
DISPLAY_SAFE_UNICODE
:/^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-\u2029\uD800-\uDFFF\uE000-\uF8FF\uFFF9-\uFFFF])*$/
DISPLAY_SAFE_UNICODE_WITH_NON_BMP
:/^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-\u2029\uE000-\uF8FF\uFFF9-\uFFFF])*$/
BEARER_AUTH_REGEX
:/^Bearer\s+([a-z0-9+\/]+)$/i
service
:string, max(16), regex(/^[a-zA-Z0-9\-]*$/)
hexString
:string, regex(/^(?:[a-fA-F0-9]{2})+$/)
clientId
:module.exports.hexString.length(16)
clientSecret
:module.exports.hexString
accessToken
:module.exports.hexString.length(64)
refreshToken
:module.exports.hexString.length(64)
authorizationCode
:module.exports.hexString.length(64)
scope
:string, max(256), regex(/^[a-zA-Z0-9 _\/.:-]*$/), allow('')
assertion
:string, min(50), max(10240), regex(/^[a-zA-Z0-9_\-\.~=]+$/)
pkceCodeChallengeMethod
:string, valid('S256')
pkceCodeChallenge
:string, length(43), regex(module, exports.URL_SAFE_BASE_64)
pkceCodeVerifier
:string, length(43), regex(module, exports.PKCE_CODE_VERIFIER)
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-_]+$/)
verificationMethod
:string, valid()
authPW
:string, length(64), regex(HEX_STRING), required
wrapKb
:string, length(64), regex(/^(?:[a-fA-F0-9]{2})+$/)
recoveryKeyId
:string, regex(HEX_STRING), max(32)
recoveryData
:string, regex(/[a-zA-Z0-9.]/), max(1024), required
E164_NUMBER
:/^\+[1-9]\d{1,14}$/
DIGITS
:/^[0-9]+$/
DEVICE_COMMAND_NAME
:/^[a-zA-Z0-9._\/\-:]{1,100}$/
IP_ADDRESS
:string, ip
lib/metrics/context
SCHEMA
: object({deviceId
: string, length(32), regex(HEX_STRING), optionalentrypoint
: ENTRYPOINT_SCHEMA.optionalentrypointExperiment
: ENTRYPOINT_SCHEMA.optionalentrypointVariation
: ENTRYPOINT_SCHEMA.optionalflowId
: string, length(64), regex(HEX_STRING), optionalflowBeginTime
: number, integer, positive, optionalutmCampaign
: UTM_CAMPAIGN_SCHEMA.optionalutmContent
: UTM_SCHEMA.optionalutmMedium
: UTM_SCHEMA.optionalutmSource
: UTM_SCHEMA.optionalutmTerm
: UTM_SCHEMA.optional }), unknown(false), and('flowId', 'flowBeginTime')
schema
: SCHEMA.optionalrequiredSchema
: SCHEMA.required
lib/features
schema
: array, items(string), optional
lib/devices
schema
: {id
: isA.string.length(32).regex(HEX_STRING)location
: isA.object({city
: isA.string.optional.allow(null)country
: isA.string.optional.allow(null)state
: isA.string.optional.allow(null)stateCode
: isA.string.optional.allow(null)- })
name
: isA.string.max(255).regex(DISPLAY_SAFE_UNICODE_WITH_NON_BMP)nameResponse
: isA.string.max(255).allow('')type
: isA.string.max(16)pushCallback
: validators.pushCallbackUrl({ scheme: 'https' }).regex(PUSH_SERVER_REGEX).max(255).allow('')pushPublicKey
: isA.string.max(88).regex(URL_SAFE_BASE_64).allow('')pushAuthKey
: isA.string.max(24).regex(URL_SAFE_BASE_64).allow('')pushEndpointExpired
: isA.boolean.strictavailableCommands
: isA.object.pattern(validators.DEVICE_COMMAND_NAME- `isA.string.max(2048))
}
During periods of heavy load, the server may request that clients enter a "back-off" state, in which they avoid making further requests.
At such times,
it will return a 503 Service Unavailable
response
with a Retry-After
header denoting the number of seconds to wait
before issuing any further requests.
It will also include errno: 201
and a retryAfter
field
matching the value of the Retry-After
header
in the body.
For example, the following response indicates that the client should suspend making further requests for 30 seconds:
HTTP/1.1 503 Service Unavailable
Retry-After: 30
Content-Type: application/json
{
"code": 503,
"errno": 201,
"error": "Service Unavailable",
"message": "Service unavailable",
"info": "https://mozilla.github.io/ecosystem-platform/api#section/Response-format",
"retryAfter": 30,
"retryAfterLocalized": "in a few seconds"
}
/account/keys
🔒 Authenticated with key fetch token
Get 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.
Since 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.
This request will fail unless the account's email address and current session has been verified.
Responses
/account/profile
🔒 Authenticated with OAuth bearer token or authenticated with session token
Get the email and locale of a user.
If an OAuth bearer token is used, the values returned depend on the scopes that the token is authorized for:
email
requiresprofile:email
scope.locale
requiresprofile:locale
scope.atLeast18AtReg
requiresprofile:age_check
scope.authenticationMethods
andauthenticatorAssuranceLevel
requireprofile:amr
scope.accountDisabledAt
requiresprofile:account_disabled_at
scope.accountLockedAt
requiresprofile:account_locked_at
scope.
The profile
scope includes all the above sub-scopes.
Responses
/account/status
Gets the status of an account without exposing user data through query params. This endpoint is rate limited by fxa-customs-server.
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... |
thirdPartyAuthStatus | boolean Default: false |
checkDomain | string |
Responses
Request samples
- Payload
{- "email": "string",
- "thirdPartyAuthStatus": false,
- "checkDomain": "string"
}
/account/create
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 wiki page.
This 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.
Creating an account also logs in. The response contains a sessionToken
and, optionally, a keyFetchToken
if the url has a query parameter of keys=true
.
query Parameters
keys | boolean Indicates whether a key-fetch token should be returned in the success response. |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Opaque alphanumeric token to be included in verification links. |
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... The primary email for this account. |
authPW required | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string. |
authPWVersion2 | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string using the version 2 key stretching. |
wrapKb | string^(?:[a-fA-F0-9]{2})+$ The new |
wrapKbVersion2 | string^(?:[a-fA-F0-9]{2})+$ The new |
clientSalt | string^identity\.mozilla\.com\/picl\/v1\/quickStret... The salt used when creating authPW. If not provided, it will be assumed that version one of the password encryption scheme was used. |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Opaque alphanumeric token to be included in verification links. |
redirectTo | string <= 2048 characters URL that the client should be redirected to after handling the request. |
resume | string <= 2048 characters Opaque URL-encoded string to be included in the verification link as a query parameter. |
object (metricsContext) | |
style | string (style) Value: "trailhead" |
verificationMethod | string (verificationMethod) Enum: "email" "email-otp" "email-2fa" "email-captcha" "totp-2fa" If this param is specified, it forces the login to be verified using the specified method. Currently supported methods:
|
atLeast18AtReg | boolean True if age submitted at signup is equal or higher than 18, otherwise null if >18, account created before this column was added or if COPPA is disabled. Used by some relying parties to verify if they need to perform another age check. |
Responses
Request samples
- Payload
{- "email": "string",
- "authPW": "string",
- "authPWVersion2": "string",
- "wrapKb": "string",
- "wrapKbVersion2": "string",
- "clientSalt": "string",
- "service": "string",
- "redirectTo": "string",
- "resume": "string",
- "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}, - "style": "trailhead",
- "verificationMethod": "email",
- "atLeast18AtReg": true
}
/account/destroy
🔒🔓 Optionally authenticated with session token
Deletes 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.
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... The primary email for this account. |
authPW required | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string. |
Responses
Request samples
- Payload
{- "email": "string",
- "authPW": "string"
}
/account/finish_setup
Request Body schema: application/json
token | string <= 1024 characters ^([a-zA-Z0-9\-_]+)\.([a-zA-Z0-9\-_]+)\.([a-zA... |
authPW required | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string. |
wrapKb | string^(?:[a-fA-F0-9]{2})+$ The new |
authPWVersion2 | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string using the version 2 key stretching. |
wrapKbVersion2 | string^(?:[a-fA-F0-9]{2})+$ The new |
clientSalt | string^identity\.mozilla\.com\/picl\/v1\/quickStret... The salt used when creating authPW. If not provided, it will be assumed that version one of the password encryption scheme was used. |
Responses
Request samples
- Payload
{- "token": "string",
- "authPW": "string",
- "wrapKb": "string",
- "authPWVersion2": "string",
- "wrapKbVersion2": "string",
- "clientSalt": "string"
}
/account/login
Obtain a sessionToken
and, optionally, a keyFetchToken
if keys=true
.
query Parameters
keys | boolean Indicates whether a key-fetch token should be returned in the success response. |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Opaque alphanumeric token to be included in verification links. |
verificationMethod | string Enum: "email" "email-otp" "email-2fa" "email-captcha" "totp-2fa" If this param is specified, it forces the login to be verified using the specified method. Currently supported methods:
|
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... The primary email for this account. |
authPW required | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string. |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Opaque alphanumeric token to be included in verification links. |
redirectTo | string <= 2048 characters |
resume | string Opaque URL-encoded string to be included in the verification link as a query parameter. |
reason | string <= 16 characters Alphanumeric string indicating the reason for establishing a new session; may be "login" (the default) or "reconnect". |
unblockCode | string^[a-zA-Z0-9]*$ Alphanumeric code used to unblock certain rate-limitings. |
object (metricsContext) | |
originalLoginEmail | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... 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. |
verificationMethod | string (verificationMethod) Enum: "email" "email-otp" "email-2fa" "email-captcha" "totp-2fa" If this param is specified, it forces the login to be verified using the specified method. Currently supported methods:
|
Responses
Request samples
- Payload
{- "email": "string",
- "authPW": "string",
- "service": "string",
- "redirectTo": "string",
- "resume": "string",
- "reason": "string",
- "unblockCode": "string",
- "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}, - "originalLoginEmail": "string",
- "verificationMethod": "email"
}
/account/reset
🔒 Authenticated with account reset token
This sets the account password and resets wrapKb
to a new random value.
Account 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.
The caller can optionally request a new sessionToken
and keyFetchToken
.
query Parameters
keys | boolean Indicates whether a new |
Request Body schema: application/json
authPW required | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string. |
authPWVersion2 | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string. |
wrapKb | string^(?:[a-fA-F0-9]{2})+$ The new |
wrapKbVersion2 | string^(?:[a-fA-F0-9]{2})+$ The new |
clientSalt | string^identity\.mozilla\.com\/picl\/v1\/quickStret... The salt used when creating authPW. If not provided, it will be assumed that version one of the password encryption scheme was used. |
recoveryKeyId | string <= 32 characters ^(?:[a-fA-F0-9]{2})+$ A unique identifier for this account recovery key, derived from the key via HKDF. |
sessionToken | boolean Indicates whether a new |
Responses
Request samples
- Payload
{- "authPW": "string",
- "authPWVersion2": "string",
- "wrapKb": "string",
- "wrapKbVersion2": "string",
- "clientSalt": "string",
- "recoveryKeyId": "string",
- "sessionToken": true
}
/account/set_password
🔒🔓 Authenticated with oauth access token.
Sets the password on an unverified stub account.
By default, a verification email will be sent.
If the user is subscribed to a product, and we find a valid, matching Stripe productId, they will be added to a list to receive verification reminder emails.
query Parameters
sendVerifyEmail | boolean Default: true Boolean indicating whether a verification email should be sent. |
Request Body schema: application/json
authPW required | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string. |
authPWVersion2 | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string using the version 2 key stretching. |
wrapKb | string^(?:[a-fA-F0-9]{2})+$ The new |
wrapKbVersion2 | string^(?:[a-fA-F0-9]{2})+$ The new |
clientSalt | string^identity\.mozilla\.com\/picl\/v1\/quickStret... The salt used when creating authPW. If not provided, it will be assumed that version one of the password encryption scheme was used. |
object (metricsContext) | |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Opaque alphanumeric token to be included in verification links. |
Responses
Request samples
- Payload
{- "authPW": "string",
- "authPWVersion2": "string",
- "wrapKb": "string",
- "wrapKbVersion2": "string",
- "clientSalt": "string",
- "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}, - "service": "string"
}
/account/stub
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... |
clientId required | string^(?:[a-fA-F0-9]{2})+$ |
object (metricsContext) | |
wantsSetupToken | boolean |
Responses
Request samples
- Payload
{- "email": "string",
- "clientId": "string",
- "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}, - "wantsSetupToken": true
}
/account/credentials/status
This provides access to the accounts some info about the format of the account credentials. If the version 2 credential format is in use, the client's unique salt will also be provided.
Request Body schema: application/json
string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... The primary email for this account. |
Responses
Request samples
- Payload
{- "email": "string"
}
/recoveryKey
🔒 Authenticated with session token
Creates 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 docs.
Request Body schema: application/json
recoveryKeyId | string <= 32 characters ^(?:[a-fA-F0-9]{2})+$ A unique identifier for this account recovery key, derived from the key via HKDF. |
recoveryData required | string <= 1024 characters [a-zA-Z0-9.] An encrypted bundle containing the user's kB. |
enabled | boolean Default: true |
replaceKey | boolean Default: false |
Responses
Request samples
- Payload
{- "recoveryKeyId": "string",
- "recoveryData": "string",
- "enabled": true,
- "replaceKey": false
}
/recoveryKey/exists
🔒🔓 Authenticated with session token or password-forgot token
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.
Request Body schema: application/json
string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... |
Responses
Request samples
- Payload
{- "email": "string"
}
/recoveryKey/hint
🔒 Authenticated with session token
This route updates the hint associated with a userʼs recovery key.
Request Body schema: application/json
hint | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... A string containing a user-defined hint to help them remember where they stored their account recovery key. |
Responses
Request samples
- Payload
{- "hint": "string"
}
/account/attached_clients
🔒 Authenticated with session token
Returns an array listing all the clients connected to the authenticated user's account, including devices, OAuth clients, and web sessions.
This endpoint is primarily designed to power the "devices and apps" view on the user's account settings page. Depending on the type of client, it will have at least one and possibly several of the following properties:
clientId
: The OAuth client_id of the connected application.sessionTokenId
: The id of thesessionToken
held by that client, if any.refreshTokenId
: The id of the OAuthrefreshToken
held by that client, if any.deviceId
: The id of the client's device record, if it has registered one.
These identifiers can be passed to /account/attached_client/destroy in order to disconnect the client.
This endpoint returns a maximum 500 last used devices and sessions.
query Parameters
filterIdleDevicesTimestamp | number Filter device list to only show devices active since UTC timestamp. |
Responses
/account/sessions Deprecated
[DEPRECATED]: Please use /account/attached_clients instead.
🔒 Authenticated with session token.
Returns an array of session objects for the authenticated user.
Responses
/account/device/commands
🔒 Authenticated with session token or authenticated with OAuth refresh token.
Fetches commands enqueued for the current device by prior calls to /account/devices/invoke_command. The device can page through the enqueued commands by using the index
and limit
parameters.
For more details, see the device registration docs.
query Parameters
index | number The index of the most recently seen command item. Only commands enqueued after the given index will be returned. |
limit | number [ 0 .. 100 ] Default: 100 The maximum number of commands to return. The default and maximum value for limit is 100. |
Responses
/account/device
🔒 Authenticated with session token or OAuth refresh token
Creates or updates the device registration 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.
pushEndpointExpired
will be reset to false on update if the tuple { pushCallback, pushPublicKey, pushAuthKey }
is specified.
Devices 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.
Request Body schema: application/json
id | string^(?:[a-fA-F0-9]{2})+$ |
name | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... |
type | string <= 16 characters |
pushCallback | string <= 255 characters ^https:\/\/[a-zA-Z0-9._-]+(\.services\.mozill... |
pushPublicKey | string <= 88 characters ^[A-Za-z0-9_-]+$ |
pushAuthKey | string <= 24 characters ^[A-Za-z0-9_-]+$ |
object | |
capabilities | Array of strings (Model61) |
Responses
Request samples
- Payload
{- "id": "string",
- "name": "string",
- "type": "string",
- "pushCallback": "string",
- "pushPublicKey": "string",
- "pushAuthKey": "string",
- "availableCommands": {
- "string": "string"
}, - "capabilities": [
- "string"
]
}
/account/attached_client/destroy
🔒 Authenticated with session token
Destroy all tokens held by a connected client, disconnecting it from the user's account.
This endpoint is designed to be used in conjunction with /account/attached_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.
Request Body schema: application/json
clientId | string^(?:[a-fA-F0-9]{2})+$ |
sessionTokenId | string^(?:[a-fA-F0-9]{2})+$ |
refreshTokenId | string^(?:[a-fA-F0-9]{2})+$ |
deviceId | string^(?:[a-fA-F0-9]{2})+$ |
Responses
Request samples
- Payload
{- "clientId": "string",
- "sessionTokenId": "string",
- "refreshTokenId": "string",
- "deviceId": "string"
}
/account/device/destroy
🔒 Authenticated with session token or authenticated with OAuth refresh token
Destroys a device record and the associated sessionToken
for the authenticated user.
Request Body schema: application/json
id required | string^(?:[a-fA-F0-9]{2})+$ |
Responses
Request samples
- Payload
{- "id": "string"
}
/account/devices/invoke_command
🔒 Authenticated with session token or authenticated with OAuth refresh token.
Enqueues a command to be invoked on a target device.
For more details, see the device registration docs.
Request Body schema: application/json
target required | string^(?:[a-fA-F0-9]{2})+$ The id of the device on which to invoke the command. |
command required | string The id of the command to be invoked, as found in the device's availableCommands set. |
payload required | object (Model119) Opaque payload to be forwarded to the device. |
ttl | integer [ 0 .. 10000000 ] The time in milliseconds after which the command should expire, if not processed by the device. |
Responses
Request samples
- Payload
{- "target": "string",
- "command": "string",
- "payload": { },
- "ttl": 10000000
}
/account/devices/notify
🔒 Authenticated with session token or authenticated with OAuth refresh token.
Notifies 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.
Request Body schema: application/json
to required | string (to) Value: "all" Devices to notify. String |
_endpointAction | string (_endpointAction) Value: "accountVerify" |
excluded | Array of strings (excluded) [^(?:[a-fA-F0-9]{2})+$] Array of device ids to exclude from the notification. Ignored unless |
payload required | object (Model122) Push payload, validated against pushpayloads.schema.json. |
TTL | integer >= 0 Push notification TTL, defaults to |
Responses
Request samples
- Payload
{- "to": "all",
- "_endpointAction": "accountVerify",
- "excluded": [
- "string"
], - "payload": { },
- "TTL": 0
}
/recovery_email/status
🔒 Authenticated with session token
Returns the 'verified' status for the account's recovery email address.
Currently, each account is associated with exactly one email address. This address must be verified before the account can be used (specifically, POST /certificate/sign
and 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.
This 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 POST /certificate/sign
and GET /account/keys
.
query Parameters
reason | string <= 16 characters |
Responses
/recovery_email
🔒 Authenticated with session token Add a secondary email address to the logged-in account. The created address will be unverified and will not replace the primary email address.
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... The email address to add to the account. |
Responses
Request samples
- Payload
{- "email": "string"
}
/recovery_email/destroy
🔒 Authenticated with session token
Delete an email address associated with the logged-in user.
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... The email address to delete. |
Responses
Request samples
- Payload
{- "email": "string"
}
/recovery_email/resend_code
🔒 Authenticated with session token
Re-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'.
This 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.
query Parameters
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Opaque alphanumeric token to be included in verification links. |
type | string <= 32 characters Value: "upgradeSession" |
Request Body schema: application/json
string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... | |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Opaque alphanumeric token to be included in verification links. |
redirectTo | string <= 2048 characters |
resume | string <= 2048 characters Opaque URL-encoded string to be included in the verification link as a query parameter. |
style | string (style) Value: "trailhead" |
type | string (type) <= 32 characters Value: "upgradeSession" |
Responses
Request samples
- Payload
{- "email": "string",
- "service": "string",
- "redirectTo": "string",
- "resume": "string",
- "style": "trailhead",
- "type": "upgradeSession"
}
/recovery_email/set_primary
🔒 Authenticated with session token
This endpoint changes a user's primary email address. This email address must belong to the user and be verified.
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... The new primary email address of the user. |
Responses
Request samples
- Payload
{- "email": "string"
}
/recovery_email/verify_code
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.
The 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.
Request Body schema: application/json
uid required | string <= 32 characters ^(?:[a-fA-F0-9]{2})+$ |
code required | string = 32 characters ^(?:[a-fA-F0-9]{2})+$ |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Opaque alphanumeric token to be included in verification links. |
reminder | string^(?:first|second|final)$ Indicates that verification originates from a reminder email. |
type | string <= 32 characters The type of code being verified. |
style | string (style) Value: "trailhead" |
marketingOptIn | boolean |
newsletters | Array of strings (Model98) Items 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" |
Responses
Request samples
- Payload
{- "uid": "string",
- "code": "stringstringstringstringstringst",
- "service": "string",
- "reminder": "string",
- "type": "string",
- "style": "trailhead",
- "marketingOptIn": true,
- "newsletters": [
- "firefox-accounts-journey"
]
}
/recovery_email/secondary/resend_code
🔒 Authenticated with session token
This endpoint resend the otp verification to verify the secondary email.
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... The secondary email address to verify. |
Responses
Request samples
- Payload
{- "email": "string"
}
/recovery_email/secondary/verify_code
🔒 Authenticated with session token
This endpoint verifies a secondary email using a time based (otp) code.
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... The secondary email address to verify. |
code required | string <= 32 characters ^[0-9]+$ Time based code to verify secondary email |
Responses
Request samples
- Payload
{- "email": "string",
- "code": "string"
}
/.well-known/browserid
Verifies a user is who they say they are using BrowserID.
It has been deprecated in newer version of Firefox desktop, though some clients still use it.
Responses
/newsletters
🔒 Authenticated with OAuth bearer token or authenticated with session token
Request Body schema: application/json
newsletters required | Array of strings (newsletters) Items 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" |
Responses
Request samples
- Payload
{- "newsletters": [
- "firefox-accounts-journey"
]
}
/oauth/id-token-verify
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.
Request Body schema: application/json
client_id required | string |
id_token required | string |
expiry_grace_period | number Default: 0 |
Responses
Request samples
- Payload
{- "client_id": "string",
- "id_token": "string",
- "expiry_grace_period": 0
}
/support/ticket
🔒 Authenticated with support secret or authenticated with OAuth bearer token
Creates a support ticket using the Zendesk client.
Request Body schema: application/json
string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... | |
productName required | string |
productPlatform | string |
productVersion | string |
topic required | string |
app | string |
subject | string |
message required | string |
product | string |
category | string |
Responses
Request samples
- Payload
{- "email": "string",
- "productName": "string",
- "productPlatform": "string",
- "productVersion": "string",
- "topic": "string",
- "app": "string",
- "subject": "string",
- "message": "string",
- "product": "string",
- "category": "string"
}
/oauth/client/{client_id}
Retrieve metadata about the specified OAuth client, such as its display name and redirect URI.
path Parameters
client_id required | string^(?:[0-9a-f]{2})+$ The OAuth client identifier for the requesting client application (provided by the connecting client application) asking for permission. |
Responses
/account/scoped-key-data
🔒 Authenticated with session token
Query for the information required to derive scoped encryption keys requested by the specified OAuth client.
Request Body schema: application/json
client_id required | string^(?:[0-9a-f]{2})+$ |
scope required | string |
Responses
Request samples
- Payload
{- "client_id": "string",
- "scope": "string"
}
/oauth/authorization
🔒 Authenticated with session token
Authorize 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.
This route behaves like the oauth-server /authorization endpoint except that it is authenticated directly with a sessionToken rather than with a BrowserID assertion.
Request Body schema: application/json
response_type | string (Model80) Default: "code" Value: "code" Determines the format of the response. Since we only support the authorization-code grant flow, the only permitted value is 'code'. |
client_id required | string^(?:[0-9a-f]{2})+$ The OAuth client identifier for the requesting client application (provided by the connecting client application) |
redirect_uri | string <= 256 characters 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. |
scope | string 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 required | string <= 512 characters 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_type | string (access_type) Default: "online" Enum: "offline" "online" If specified, a value of |
code_challenge_method | string (code_challenge_method) Value: "S256" Required for public OAuth clients, who must authenticate their authorization code use via PKCE. The only support method is 'S256', no other value is accepted. |
code_challenge | string^[A-Za-z0-9_-]+$ Required for public OAuth clients, who must authenticate their authorization code use via PKCE. A minimum length of 43 characters and a maximum length of 128 characters string, encoded as |
keys_jwe | string <= 1024 characters ^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*\.[A-Za-z0-9-_... An encrypted JWE bundle of key material, to be returned to the client when it redeems the authorization code. |
acr_values | string <= 256 characters A space-separated list of ACR values specifying acceptable levels of user authentication that the token should have a claim for. Specifying |
Responses
Request samples
- Payload
{- "response_type": "code",
- "client_id": "string",
- "redirect_uri": "string",
- "scope": "string",
- "state": "string",
- "access_type": "offline",
- "code_challenge_method": "S256",
- "code_challenge": "string",
- "keys_jwe": "string",
- "acr_values": "string"
}
/oauth/destroy
Destroy an OAuth access token or refresh token.
This 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.
One of either an authorization header or a client_id is required.
header Parameters
authorization | string^Basic\s+([a-zA-Z0-9+=\/]+)$ |
Request Body schema: application/json
client_id required | string^(?:[0-9a-f]{2})+$ The OAuth client identifier for the requesting client application (provided by the connecting client application) |
client_secret | string^(?:[0-9a-f]{2})+$ The OAuth client secret for the requesting client application. Required for confidential clients, forbidden for public clients. |
token | string^(?:[0-9a-f]{2})+$ |
token_type_hint | string <= 64 characters 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. |
Responses
Request samples
- Payload
{- "client_id": "string",
- "client_secret": "string",
- "token": "string",
- "token_type_hint": "string"
}
/oauth/token
🔒🔓 Optionally authenticated with session token
Grant new OAuth tokens for use by a connected client, using one of the following grant types:
grant_type=authorization_code
: A single-use code obtained via OAuth redirect flow.grant_type=refresh_token
: A refresh token issued by a previous call to this endpoint.grant_type=fxa-credentials
: Directly grant tokens using an FxA sessionToken.
This is the "token endpoint" as defined in RFC6749, and behaves like the oauth-server /token endpoint except that the fxa-credentials
grant can be authenticated directly with a sessionToken rather than with a BrowserID assertion.
Request Body schema: application/json
grant_type | string (Model86) Default: "authorization_code" Value: "authorization_code" 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:
|
client_id required | string^(?:[0-9a-f]{2})+$ The OAuth client identifier for the requesting client application (provided by the connecting client application) |
client_secret | string^(?:[0-9a-f]{2})+$ The OAuth client secret for the requesting client application. Required for confidential clients, forbidden for public clients. |
code required | string^(?:[a-fA-F0-9]{2})+$ |
code_verifier | string [ 43 .. 128 ] characters ^[A-Za-z0-9-\._~]{43,128}$ |
redirect_uri | string |
ttl | number 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 |
ppid_seed | integer [ 0 .. 1024 ] Default: 0 Seed used in |
resource | string# 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 |
Responses
Request samples
- Payload
{- "grant_type": "authorization_code",
- "client_id": "string",
- "client_secret": "string",
- "code": "string",
- "code_verifier": "stringstringstringstringstringstringstrings",
- "redirect_uri": "string",
- "ttl": 0,
- "ppid_seed": 0,
- "resource": "string"
}
/password/create
🔒 Authenticated with session token
Creates a new password for the user associated with the session token. Creating a new password will generate new encryption key.
Request Body schema: application/json
authPW required | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string. |
authPWVersion2 | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string using the version 2 key stretching. |
wrapKb | string^(?:[a-fA-F0-9]{2})+$ The new |
wrapKbVersion2 | string^(?:[a-fA-F0-9]{2})+$ The new |
clientSalt | string^identity\.mozilla\.com\/picl\/v1\/quickStret... The salt used when creating authPW. If not provided, it will be assumed that version one of the password encryption scheme was used. |
Responses
Request samples
- Payload
{- "authPW": "string",
- "authPWVersion2": "string",
- "wrapKb": "string",
- "wrapKbVersion2": "string",
- "clientSalt": "string"
}
/password/change/finish
🔒 Authenticated with password change token
Change the password and update wrapKb
. Optionally returns sessionToken
and keyFetchToken
.
query Parameters
keys | boolean Indicates whether a new |
Request Body schema: application/json
authPW required | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string. |
authPWVersion2 | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string. |
wrapKb | string^(?:[a-fA-F0-9]{2})+$ The new |
wrapKbVersion2 | string^(?:[a-fA-F0-9]{2})+$ The new |
clientSalt | string^identity\.mozilla\.com\/picl\/v1\/quickStret... The salt used when creating authPW. If not provided, it will be assumed that version one of the password encryption scheme was used. |
sessionToken | string = 64 characters ^(?:[a-fA-F0-9]{2})+$ Indicates whether a new |
Responses
Request samples
- Payload
{- "authPW": "string",
- "authPWVersion2": "string",
- "wrapKb": "string",
- "wrapKbVersion2": "string",
- "clientSalt": "string",
- "sessionToken": "stringstringstringstringstringstringstringstringstringstringstri"
}
/password/change/start
Begin the "change password" process. Returns a single-use passwordChangeToken
, to be sent to POST /password/change/finish
. Also returns a single-use keyFetchToken
.
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... The primary email for this account. |
oldAuthPW required | string^(?:[a-fA-F0-9]{2})+$ The PBKDF2/HKDF-stretched password as a hex string. |
Responses
Request samples
- Payload
{- "email": "string",
- "oldAuthPW": "string"
}
/password/forgot/resend_code
🔒 Authenticated with password forgot token
Resends the email from POST /password/forgot/send_code
, for use when the original email has been lost or accidentally deleted.
This endpoint requires the passwordForgotToken
returned in the original response, so only the original client which started the process may request a resent message. The response will match that from POST /password/forgot/send_code
, except ttl
will be lower to indicate the shorter validity period. tries
will also be lower if POST /password/forgot/verify_code
has been called.
query Parameters
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Identifies the relying service the user was interacting with that triggered the password reset. |
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... Recovery email for the account. |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Identifies the relying service the user was interacting with that triggered the password reset. |
redirectTo | string <= 2048 characters URL that the client should be redirected to after handling the request. |
resume | string <= 2048 characters Opaque URL-encoded string to be included in the verification link as a query parameter. |
Responses
Request samples
- Payload
{- "email": "string",
- "service": "string",
- "redirectTo": "string",
- "resume": "string"
}
/password/forgot/send_code
Requests a 'reset password' code to be sent to the user's recovery email. The user should type this code into the agent, which will then submit it to POST /password/forgot/verify_code
.
The code will be either 8 or 16 digits long, with the length indicated in the response. The email will either contain the code itself or the URL for a web page that displays the code.
The response includes passwordForgotToken
, which must be submitted with the code to POST /password/forgot/verify_code
.
The response also specifies the TTL of passwordForgotToken
and an upper limit on the number of times the token may be submitted. By limiting the number of submission attempts, we also limit an attacker's ability to guess the code. After the token expires, or the maximum number of submissions has been made, the agent must call this endpoint again to generate a new code and token pair.
Each account can have at most one passwordForgotToken
valid at a time. Calling this endpoint causes existing tokens to be invalidated and a new one created. Each token is associated with a specific code, so by extension the codes are invalidated with their tokens.
query Parameters
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Identifies the relying service the user was interacting with that triggered the password reset. |
keys | boolean |
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... Recovery email for the account. |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Identifies the relying service the user was interacting with that triggered the password reset. |
redirectTo | string <= 2048 characters URL that the client should be redirected to after handling the request. |
resume | string <= 2048 characters Opaque URL-encoded string to be included in the verification link as a query parameter. |
object (metricsContext) |
Responses
Request samples
- Payload
{- "email": "string",
- "service": "string",
- "redirectTo": "string",
- "resume": "string",
- "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}
}
/password/forgot/send_otp
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.
query Parameters
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Identifies the relying service the user was interacting with that triggered the password reset. |
keys | boolean |
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... Recovery email for the account. |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ Identifies the relying service the user was interacting with that triggered the password reset. |
object (metricsContext) |
Responses
Request samples
- Payload
{- "email": "string",
- "service": "string",
- "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}
}
/password/forgot/verify_code
🔒 Authenticated with password forgot token
The 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
.
Request Body schema: application/json
code required | string = 32 characters ^(?:[a-fA-F0-9]{2})+$ The code sent to the user's recovery email. |
accountResetWithRecoveryKey | boolean |
Responses
Request samples
- Payload
{- "code": "stringstringstringstringstringst",
- "accountResetWithRecoveryKey": true
}
/password/forgot/verify_otp
Verify the OTP from /password/forgot/send_otp
to receive the PasswordForgotToken and its code to continue the password reset process.
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... Recovery email for the account. |
code | string^[0-9]+$ |
object (metricsContext) |
Responses
Request samples
- Payload
{- "email": "string",
- "code": "string",
- "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}
}
/session/destroy
🔒 Authenticated with session token
Destroys 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
.
Request Body schema: application/json
customSessionToken | string = 64 characters ^(?:[a-fA-F0-9]{2})+$ Custom session token id to destroy. |
Responses
Request samples
- Payload
{- "customSessionToken": "stringstringstringstringstringstringstringstringstringstringstri"
}
/session/duplicate
🔒 Authenticated with session token
Create 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.
Request Body schema: application/json
reason | string <= 16 characters |
Responses
Request samples
- Payload
{- "reason": "string"
}
/session/reauth
🔒 Authenticated with session token
Re-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.
query Parameters
keys | boolean |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ |
verificationMethod | string Enum: "email" "email-otp" "email-2fa" "email-captcha" "totp-2fa" |
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... |
authPW required | string^(?:[a-fA-F0-9]{2})+$ |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ |
redirectTo | string <= 2048 characters |
resume | string |
reason | string <= 16 characters |
unblockCode | string^[a-zA-Z0-9]*$ |
object (metricsContext) | |
originalLoginEmail | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... |
verificationMethod | string (Model102) Enum: "email" "email-otp" "email-2fa" "email-captcha" "totp-2fa" |
Responses
Request samples
- Payload
{- "email": "string",
- "authPW": "string",
- "service": "string",
- "redirectTo": "string",
- "resume": "string",
- "reason": "string",
- "unblockCode": "string",
- "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}, - "originalLoginEmail": "string",
- "verificationMethod": "email"
}
/session/verify_code
🔒 Authenticated with session token
Request Body schema: application/json
code | string^[0-9]+$ |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ |
scopes | Array of strings (scopes) [^[a-zA-Z0-9 _\/.:-]*$] |
marketingOptIn | boolean |
newsletters | Array of strings (Model106) Items 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" |
object (metricsContext) |
Responses
Request samples
- Payload
{- "code": "string",
- "service": "string",
- "scopes": [
- "string"
], - "marketingOptIn": true,
- "newsletters": [
- "firefox-accounts-journey"
], - "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}
}
/certificate/sign
🔒 Authenticated with session token
Sign a BrowserID public key. The server is given a public key and returns a signed certificate using the same JWT-like mechanism as a BrowserID primary IdP would (see browserid-certifier for details). The signed certificate includes a principal.email
property to indicate the Firefox Account identifier (a UUID at the account server's primary domain) and is stamped with an expiry time based on the duration
parameter.
This request will fail unless the primary email address for the account has been verified.
Clients should include a query parameter, service
, for metrics and validation purposes. The value of service
should be sync
when connecting to Firefox Sync or the OAuth client_id
when connecting to an OAuth relier.
If you do not specify a service parameter
, or if you specify service=sync
, this endpoint assumes the request is from a legacy Sync client. If the session token doesn't have a corresponding device record, one will be created automatically by the server.
The signed certificate includes these additional claims:
fxa-generation
: A number that increases each time the user's password is changed.fxa-keysChangedAt
: A timestamp that increases each time the user's encryption key is changed.fxa-profileChangedAt
: A timestamp that increases each time the user's core profile data is changed.fxa-lastAuthAt
: Authentication time for this session, in seconds since epoch.fxa-verifiedEmail
: The user's verified recovery email address.fxa-tokenVerified
: A boolean indicating whether the user's login was verified using an email confirmation or 2FA in addition to their password.fxa-amr
: A list of strings giving the ways in which the user was authenticated. Possible values include:pwd
: the user provided the account passwordemail
: the user completed an email confirmation loopotp
: the user completed a 2FA challenge
fxa-aal
: An integer giving the authenticator assurance level at which the user was authenticated - that is, the number of independent auth factors that they provided during login.
query Parameters
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ |
Request Body schema: application/json
required | object (publicKey) The key to sign (run bin/generate-keypair from browserid-crypto). |
duration required | integer [ 0 .. 86400000 ] Time interval in milliseconds until the certificate will expire, up to a maximum of 24 hours. |
Responses
Request samples
- Payload
{- "publicKey": {
- "algorithm": "RS",
- "n": "string",
- "e": "string",
- "y": "string",
- "p": "string",
- "q": "string",
- "g": "string",
- "version": "string"
}, - "duration": 86400000
}
/oauth/subscriptions/clients
🔒 Authenticated with OAuth bearer token
Returns a list of clients and their capabilities.
Responses
/oauth/subscriptions/productname
Returns the product name of a valid Stripe productId
(does not apply to IAP).
query Parameters
productId required | string A unique identifier for the product purchased. |
Responses
/oauth/subscriptions/invoice/preview-subsequent
🔒 Authenticated with OAuth bearer token
Previews a list of subsequent invoices based on existing subscriptions and the customer's subscriptionId
; includes estimated tax (based on the customer's last known geolocation) and any discount from a promotion code.
Responses
/oauth/mozilla-subscriptions/customer/plan-eligibility/{planid}
🔒 Authenticated with OAuth bearer token
Get eligibility for a given plan. Returns eligibility as 'create'|'upgrade'|'downgrade'|'blocked_iap'|'invalid'.
path Parameters
planId required | string <= 255 characters A unique identifier for the plan. |
Responses
/oauth/subscriptions/coupon
Retrieves coupon details of a valid plan and promotion code.
Request Body schema: application/json
priceId required | string <= 255 characters A unique identifier for the price. |
promotionCode required | string A customer-redeemable code for a coupon. |
Responses
Request samples
- Payload
{- "priceId": "string",
- "promotionCode": "string"
}
/oauth/subscriptions/paypal-checkout
Retrieves token authorizing transaction to move to the next stage of PayPal checkout.
Request Body schema: application/json
currencyCode required | string The three-letter ISO currency code, in uppercase. |
Responses
Request samples
- Payload
{- "currencyCode": "string"
}
/oauth/subscriptions/reactivate
🔒 Authenticated with OAuth bearer token
Reactivate valid Stripe/PayPal customer subscription (does not apply to IAP).
Request Body schema: application/json
subscriptionId required | string <= 255 characters A unique identifier for the Stripe subscription. |
Responses
Request samples
- Payload
{- "subscriptionId": "string"
}
/oauth/subscriptions/active/new
🔒 Authenticated with OAuth bearer token
Subscribe the user to a price using a payment method id.
Request Body schema: application/json
priceId required | string A unique identifier for the price. |
paymentMethodId | string <= 30 characters A unique identifier for the payment method in Stripe; does not apply to IAP subscriptions. |
promotionCode | string A customer-redeemable code for a coupon. |
object (metricsContext) |
Responses
Request samples
- Payload
{- "priceId": "string",
- "paymentMethodId": "string",
- "promotionCode": "string",
- "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}
}
/oauth/subscriptions/active/new-paypal
Create subscription for the provided customer using PayPal.
Request Body schema: application/json
priceId required | string A unique identifier for the price. |
promotionCode | string A customer-redeemable code for a coupon. |
token | string <= 30 characters |
idempotencyKey required | string The idempotency key transmitted during the request, if any. For more information, see Stripe docs |
object (metricsContext) |
Responses
Request samples
- Payload
{- "priceId": "string",
- "promotionCode": "string",
- "token": "string",
- "idempotencyKey": "string",
- "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}
}
/oauth/subscriptions/iap/app-store-notification
🔒 payload validated against Apple certificates
Update stored purchase information with latest subscription status.
Request Body schema: application/json
signedPayload required | string |
Responses
Request samples
- Payload
{- "signedPayload": "string"
}
/oauth/subscriptions/invoice/preview
Previews an invoice for a new plan where the user is not yet subscribed (and therefore there is no subscriptionId
); includes estimated tax (based on the user's geolocation) and any discount from a promotion code.
Request Body schema: application/json
priceId required | string <= 255 characters A unique identifier for the price. |
promotionCode | string A customer-redeemable code for a coupon. |
Responses
Request samples
- Payload
{- "priceId": "string",
- "promotionCode": "string"
}
oauth/subscriptions/invoice/retry
🔒 Authenticated with OAuth bearer token
Retry an incomplete subscription invoice with a new payment method id.
Request Body schema: application/json
invoiceId required | string A unique identifer for an invoice to Stripe/PayPal customers whose subscriptions are managed by Stripe. |
paymentMethodId required | string <= 30 characters A unique identifier for the payment method in Stripe; does not apply to IAP subscriptions. |
idempotencyKey required | string The idempotency key transmitted during the request, if any. For more information, see Stripe docs |
Responses
Request samples
- Payload
{- "invoiceId": "string",
- "paymentMethodId": "string",
- "idempotencyKey": "string"
}
/oauth/subscriptions/paymentmethod/billing-agreement
🔒 Authenticated with OAuth bearer token
Updates the billing agreement for a user with a new PayPal token.
Request Body schema: application/json
token required | string <= 30 characters |
Responses
Request samples
- Payload
{- "token": "string"
}
/oauth/subscriptions/paymentmethod/default
🔒 Authenticated with OAuth bearer token
Update a user's default payment method for invoices to the attached payment method id.
Request Body schema: application/json
paymentMethodId required | string <= 30 characters A unique identifier for the payment method in Stripe; does not apply to IAP subscriptions. |
Responses
Request samples
- Payload
{- "paymentMethodId": "string"
}
/oauth/subscriptions/iap/app-store-transaction/{appName}
🔒 authenticated with OAuth bearer token
Validate and store an App Store Original Transaction ID for the given user. Returns token validity.
path Parameters
appName required | string |
Request Body schema: application/json
originalTransactionId required | string |
Responses
Request samples
- Payload
{- "originalTransactionId": "string"
}
/oauth/subscriptions/iap/play-token/{appName}
🔒 Authenticated with OAuth bearer token
Validate and store a Play Store Puchase Token for the given user. Returns token validity.
path Parameters
appName required | string |
Request Body schema: application/json
sku required | string |
token required | string |
Responses
Request samples
- Payload
{- "sku": "string",
- "token": "string"
}
/oauth/subscriptions/paymentmethod/failed/detach
🔒 Authenticated with OAuth bearer token
Detaches a payment method from a Stripe customer without any subscriptions. This is only for Stripe customers; excludes customers using PayPal, Apple, Google, etc).
Request Body schema: application/json
paymentMethodId required | string <= 30 characters A unique identifier for the payment method in Stripe; does not apply to IAP subscriptions. |
Responses
Request samples
- Payload
{- "paymentMethodId": "string"
}
/oauth/subscriptions/active/{subscriptionId}
🔒 Authenticated with OAuth bearer token
Updates an active subscription for Stripe customer based on their Stripe subscriptionId
(does not apply to IAP).
path Parameters
subscriptionId required | string <= 255 characters A unique identifier for the Stripe subscription. |
Request Body schema: application/json
planId required | string <= 255 characters A unique identifier for the plan. |
Responses
Request samples
- Payload
{- "planId": "string"
}
/oauth/subscriptions/active/{subscriptionid}
🔒 Authenticated with OAuth bearer token
Cancel an active subscription for the user.
path Parameters
subscriptionId required | string <= 255 characters A unique identifier for the Stripe subscription. |
Responses
/oauth/subscriptions/coupon/apply
Applies an existing, valid promotion code to an active customer subscription.
Note:
- The coupon can only be applied to the upcoming invoice, as current invoices are finalized and cannot be editable
- This endpoint checks that the customer ID associated with the subscription ID matches the Stripe customer ID of the FxA user
- The promotion code needs to be included within the metadata of either the product or specific plan
Request Body schema: application/json
promotionId required | string The id associated with the promotion code |
subscriptionId required | string <= 255 characters A unique identifier for the Stripe subscription. |
Responses
Request samples
- Payload
{- "promotionId": "string",
- "subscriptionId": "string"
}
/linked_account/login
Request Body schema: application/json
idToken | string <= 1024 characters ^([a-zA-Z0-9\-_]+)\.([a-zA-Z0-9\-_]+)\.([a-zA... |
provider required | string (provider) <= 256 characters Enum: "google" "apple" |
code | string |
object (metricsContext) | |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ |
Responses
Request samples
- Payload
{- "idToken": "string",
- "provider": "google",
- "code": "string",
- "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}, - "service": "string"
}
/totp/create
🔒 Authenticated with session token
Create a new randomly generated TOTP token for a user if they do not currently have one.
Request Body schema: application/json
object (metricsContext) | |||||||||||||||||||||||||||
|
Responses
Request samples
- Payload
{- "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}
}
/session/verifiy/totp
🔒 Authenticated with session token
Verifies the current session if the passed TOTP code is valid.
Request Body schema: application/json
code required | string <= 32 characters ^[0-9]+$ The TOTP code to check |
service | string <= 16 characters ^[a-zA-Z0-9\-]*$ |
Responses
Request samples
- Payload
{- "code": "string",
- "service": "string"
}
/account/login/reject_unblock_code
Used to reject and report unblock codes that were not requested by the user.
Request Body schema: application/json
uid required | string <= 32 characters ^(?:[a-fA-F0-9]{2})+$ The user id. |
unblockCode required | string^[a-zA-Z0-9]*$ Alphanumeric code used to unblock certain rate-limitings. |
Responses
Request samples
- Payload
{- "uid": "string",
- "unblockCode": "string"
}
/account/login/send_unblock_code
Send an unblock code via email to reset rate-limiting for an account.
Request Body schema: application/json
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... The primary email for this account. |
object (metricsContext) |
Responses
Request samples
- Payload
{- "email": "string",
- "metricsContext": {
- "deviceId": "string",
- "entrypoint": "string",
- "entrypointExperiment": "string",
- "entrypointVariation": "string",
- "flowId": "string",
- "flowBeginTime": 0,
- "utmCampaign": "page+referral+-+not+part+of+a+campaign",
- "utmContent": "string",
- "utmMedium": "string",
- "utmSource": "string",
- "utmTerm": "string",
- "productId": "string",
- "planId": "string"
}
}
/complete_reset_password
query Parameters
email required | string <= 255 characters ^(?:[^\u0000-\u001F\u007F\u0080-\u009F\u2028-... |
code required | string <= 32 characters ^(?:[a-fA-F0-9]{2})+$ |
token required | string <= 64 characters ^(?:[a-fA-F0-9]{2})+$ |
service | string <= 16 characters |
redirectTo | string <= 2048 characters |
Responses
https://<server-url>/v1/<api-endpoint>
Note that:
- All API access must be over HTTPS
- The URL embeds a version identifier "v1"; future versions of this API may introduce new version numbers.
- The base URL of the server may be configured on a per-client basis.
Invalid requests will return 4XX responses. Internal failures will return 5XX. Both will include JSON responses describing the error.
Example error:
{
"code": 400, // matches the HTTP status code
"errno": 101, // stable application-level error number
"error": "Bad Request", // string description of error type
"message": "Unknown client"
}
The currently-defined error responses are:
status code | errno | description |
---|---|---|
400 | 101 | unknown client id |
400 | 102 | incorrect client secret |
400 | 103 | redirect_uri doesn't match registered value |
401 | 104 | invalid fxa assertion |
400 | 105 | unknown code |
400 | 106 | incorrect code |
400 | 107 | expired code |
400 | 108 | invalid token |
400 | 109 | invalid request parameter |
400 | 110 | invalid response_type |
401 | 111 | unauthorized |
403 | 112 | forbidden |
415 | 113 | invalid content type |
400 | 114 | invalid scopes |
400 | 115 | expired token |
400 | 116 | not a public client |
400 | 117 | incorrect code_challenge |
400 | 118 | pkce parameters missing |
400 | 119 | stale authentication timestamp |
400 | 120 | mismatch acr value |
400 | 121 | invalid grant_type |
500 | 999 | internal server error |
/v1/authorization
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.
Responses
Request samples
- JavaScript
curl -v "https://oauth.accounts.firefox.com/v1/authorization?client_id=5901bd09376fadaa&state=1234&scope=profile:email&action=signup"
/v1/authorization
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.
Request Body schema: application/json
client_id required | string^(?:[0-9a-f]{2})+$ The OAuth client identifier for the requesting client application (provided by the connecting client application) returned from client registration. |
assertion required | string [ 50 .. 10240 ] characters ^[a-zA-Z0-9_\-\.~=]+$ A FxA assertion for the signed-in user. |
redirect_uri | string <= 256 characters 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. |
scope required | string 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 | string (response_type) Default: "code" Enum: "code" "token" 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.
|
state | string <= 512 characters 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. |
ttl | number Default: 86400 Indicates the requested lifespan in seconds for the |
access_type | string (access_type) Default: "online" Enum: "offline" "online" If specified, a value of |
code_challenge_method required | string (code_challenge_method) Value: "S256" Required for public OAuth clients, who must authenticate their authorization code use via PKCE. The only support method is 'S256', no other value is accepted. |
code_challenge | string Required for public OAuth clients, who must authenticate their authorization code use via PKCE. A minimum length of 43 characters and a maximum length of 128 characters string, encoded as |
keys_jwe | string <= 1024 characters ^[A-Za-z0-9-_]+\.[A-Za-z0-9-_]*\.[A-Za-z0-9-_... An encrypted JWE bundle of key material, to be returned to the client when it redeems the authorization code. |
acr_values | string <= 256 characters A space-separated list of ACR values specifying acceptable levels of user authentication that the token should have a claim for. Specifying |
resource | string# 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 |
Responses
Request samples
- Payload
- JavaScript
{- "client_id": "string",
- "assertion": "stringstringstringstringstringstringstringstringst",
- "redirect_uri": "string",
- "scope": "string",
- "response_type": "code",
- "state": "string",
- "ttl": 86400,
- "access_type": "offline",
- "code_challenge_method": "S256",
- "code_challenge": "string",
- "keys_jwe": "string",
- "acr_values": "string",
- "resource": "string"
}
/v1/jwks
This endpoint returns the JWKs that are used for signing OpenID Connect id tokens.
Responses
Request samples
- JavaScript
curl -v "http://oauth.accounts.firefox.com/v1/jwks"
/v1/client/{client_id}
This endpoint is for the fxa-content-server to retrieve information about a client to show in its user interface.
path Parameters
client_id required | string^(?:[0-9a-f]{2})+$ The OAuth client identifier for the requesting client application (provided by the connecting client application) asking for permission. |
Responses
Request samples
- JavaScript
curl -v "http://oauth.accounts.firefox.com/v1/client/5901bd09376fadaa"
/v1/authorized-clients
This endpoint returns a list of all OAuth client instances connected to the user's account, including the the scopes granted to each client instance and the time at which it was last active, if available. It must be authenticated with an identity assertion for the user's account.
Request Body schema: application/json
assertion required | string [ 50 .. 10240 ] characters ^[a-zA-Z0-9_\-\.~=]+$ A FxA assertion for the signed-in user. |
Responses
Request samples
- Payload
- JavaScript
{- "assertion": "stringstringstringstringstringstringstringstringst"
}
/v1/destroy
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.
Request Parameters
token|access_token|refresh_token|refresh_token_id
: The hex string access token. By default,token
is assumed to be the access token.
header Parameters
authorization | string^Basic\s+([a-zA-Z0-9+=\/]+)$ |
Request Body schema: application/json
client_id | string^(?:[0-9a-f]{2})+$ The OAuth client identifier for the requesting client application (provided by the connecting client application) |
client_secret | string^(?:[0-9a-f]{2})+$ The OAuth client secret for the requesting client application. Required for confidential clients, forbidden for public clients. |
access_token | string^(?:[0-9a-f]{2})+$ |
refresh_token | string^(?:[0-9a-f]{2})+$ |
refresh_token_id | string^(?:[0-9a-f]{2})+$ The specific |
Responses
Request samples
- Payload
- JavaScript
{- "client_id": "string",
- "client_secret": "string",
- "access_token": "string",
- "refresh_token": "string",
- "refresh_token_id": "string"
}