API reference
Authentication
Log in, refresh tokens, sessions, email verification and password reset.
19 operationsBase URL https://packetexchange.io/api/v1Postman collection
BrowseAuthentication
Create an account
POST/
- Access
- Public. No key needed.
- Rate limit
- 200 requests per hour
Creates the account, emails a verification link and signs you in. acceptTerms must be true. An invite code, when given, adds test credit once the email is verified. Returns the same session payload as login.
Request body (application/json)
| Field | Type | Description |
|---|---|---|
emailrequired | string (email) | - |
passwordrequired | string | -max 128 chars |
contactNamerequired | string | -max 255 chars |
companyName | string | -max 255 chars |
country | string | -max 2 chars |
inviteCode | string | - |
acceptTermsrequired | boolean | -One of true |
Response 201
| Field | Type | Description |
|---|---|---|
datarequired | object | - |
accessTokenrequireddata.accessToken | string | JWT access token. Send as Authorization: Bearer <token>. |
refreshTokenrequireddata.refreshToken | string | Refresh token (7 days). Also set as an httpOnly cookie scoped to /api/v1/auth. |
expiresInrequireddata.expiresIn | integer | Access-token lifetime in seconds (900) |
userrequireddata.user | object | - |
idrequireddata.user.id | string (uuid) | - |
emailrequireddata.user.email | string (email) | - |
contactNamerequireddata.user.contactName | string | - |
companyNamerequireddata.user.companyName | string | null | - |
jobTitlerequireddata.user.jobTitle | string | null | - |
phonerequireddata.user.phone | string | null | - |
countryrequireddata.user.country | string | null | ISO-3166-1 alpha-2 |
timezonerequireddata.user.timezone | string | - |
companyLogoUrlrequireddata.user.companyLogoUrl | string | null | - |
avatarUrlrequireddata.user.avatarUrl | string | null | - |
rolerequireddata.user.role | string | -One of user, admin |
statusrequireddata.user.status | string | -One of active, suspended |
accountKindrequireddata.user.accountKind | string | - |
balancerequireddata.user.balance | money | USD as a decimal string with exactly 6 places, e.g. "0.012500". |
testCreditrequireddata.user.testCredit | money | Sandbox credit, spendable only by test API keys USD as a decimal string with exactly 6 places, e.g. "0.012500". |
emailVerifiedAtrequireddata.user.emailVerifiedAt | string (date-time) | null | ISO-8601 timestamp (UTC) |
pendingEmailrequireddata.user.pendingEmail | string | null | An address change waiting for confirmation |
verificationStatusrequireddata.user.verificationStatus | string | -One of unverified, verified |
kycStatusrequireddata.user.kycStatus | string | -One of not_started, pending, verified, rejected |
totpEnabledrequireddata.user.totpEnabled | boolean | Two-factor authentication is on |
taxIdrequireddata.user.taxId | string | null | - |
taxCountryrequireddata.user.taxCountry | string | null | - |
payoutMethodrequireddata.user.payoutMethod | string | null | - |
onboardingGoalrequireddata.user.onboardingGoal | string | null | - |
onboardingDismissedrequireddata.user.onboardingDismissed | boolean | - |
onboardingSeenrequireddata.user.onboardingSeen | boolean | - |
emailNotificationsOptOutrequireddata.user.emailNotificationsOptOut | boolean | - |
switchStatusrequireddata.user.switchStatus | string | -One of none, active, past_due, canceled, comp |
createdAtrequireddata.user.createdAt | string (date-time) | ISO-8601 timestamp (UTC) |
updatedAtrequireddata.user.updatedAt | string (date-time) | ISO-8601 timestamp (UTC) |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Log in with email and password
POST/
- Access
- Public. No key needed.
- Rate limit
- 20 requests per 5 minutes
Returns an access token, a refresh token and your profile. When two-factor authentication is on, returns { mfaRequired: true, mfaToken } instead: complete the login with POST /auth/2fa/verify. Repeated failures lock the account temporarily.
Request body (application/json)
| Field | Type | Description |
|---|---|---|
emailrequired | string (email) | - |
passwordrequired | string | -max 128 chars |
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | - |
accessTokendata.accessToken | string | JWT access token. Send as Authorization: Bearer <token>. |
refreshTokendata.refreshToken | string | Refresh token (7 days). Also set as an httpOnly cookie scoped to /api/v1/auth. |
expiresIndata.expiresIn | integer | Access-token lifetime in seconds (900) |
userdata.user | object | Same fields as AccountProfile, shown earlier on this page. |
mfaRequireddata.mfaRequired | boolean | -One of true |
mfaTokendata.mfaToken | string | Short-lived (5 minutes) token to send with a TOTP code to POST /auth/2fa/verify |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Complete a two-factor login
POST/
- Access
- Public. No key needed.
- Rate limit
- 15 requests per 5 minutes
Exchanges the mfaToken from login plus an authenticator (or backup) code for a session.
Request body (application/json)
| Field | Type | Description |
|---|---|---|
mfaTokenrequired | string | From the login response |
coderequired | string | 6-digit authenticator code, or one of your backup codes |
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | Same fields as AuthSession, shown earlier on this page. |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Refresh an access token
POST/
- Access
- Public. No key needed.
- Rate limit
- 100 requests per second (the default)
Reads the refresh token from the httpOnly cookie, or from the body for non-browser clients. Rotates the refresh token: store the new one. Cross-site browser requests are refused with CSRF_BLOCKED; a missing token is MISSING_TOKEN.
Request body (application/json)
| Field | Type | Description |
|---|---|---|
refreshToken | string | - |
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | - |
accessTokenrequireddata.accessToken | string | JWT access token. Send as Authorization: Bearer <token>. |
refreshTokenrequireddata.refreshToken | string | Refresh token (7 days). Also set as an httpOnly cookie scoped to /api/v1/auth. |
expiresInrequireddata.expiresIn | integer | Access-token lifetime in seconds (900) |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support. - Also
MISSING_TOKEN,CSRF_BLOCKED
Log out the current session
POST/
- Access
- API key. Full-access keys only; not reachable by scoped keys.
- Rate limit
- 100 requests per second (the default)
Revokes only this session (other devices stay signed in) and clears the refresh cookie.
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | - |
messagerequireddata.message | string | - |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 401
UNAUTHORIZED: missing, invalid, expired or revoked credential. - 403
FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
List your active sessions
GET/
- Access
- Dashboard session. API keys are refused with 403. Use a login access token.
- Rate limit
- 100 requests per second (the default)
Signed-in devices, most recently seen first. current marks the one making the request.
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object[] | - |
idrequireddata[].id | string (uuid) | - |
iprequireddata[].ip | string | null | - |
userAgentrequireddata[].userAgent | string | null | - |
createdAtrequireddata[].createdAt | string (date-time) | ISO-8601 timestamp (UTC) |
lastSeenAtrequireddata[].lastSeenAt | string (date-time) | null | ISO-8601 timestamp (UTC) |
currentrequireddata[].current | boolean | True for the session making this request (matched via the refresh token) |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 401
UNAUTHORIZED: missing, invalid, expired or revoked credential. - 403
FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Sign out one session
DELETE/
- Access
- Dashboard session. API keys are refused with 403. Use a login access token.
- Rate limit
- 100 requests per second (the default)
Parameters
| Name | In | Type | Description |
|---|---|---|---|
idrequired | path | string | - |
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | Same fields as Message, shown earlier on this page. |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 401
UNAUTHORIZED: missing, invalid, expired or revoked credential. - 403
FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only. - 404
NOT_FOUND: no such resource on your account. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Sign out every other session
POST/
- Access
- Dashboard session. API keys are refused with 403. Use a login access token.
- Rate limit
- 100 requests per second (the default)
Keeps the current session. Needs the refresh token (cookie or body) to know which session is current; without it the answer is NO_SESSION.
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | Same fields as Message, shown earlier on this page. |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 401
UNAUTHORIZED: missing, invalid, expired or revoked credential. - 403
FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support. - Also
NO_SESSION
Verify your email address
POST/
- Access
- Public. No key needed.
- Rate limit
- 100 requests per second (the default)
Consumes the token from the verification email. Any invite-code test credit is added at this point.
Request body (application/json)
| Field | Type | Description |
|---|---|---|
tokenrequired | string | - |
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | Same fields as Message, shown earlier on this page. |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Confirm an email address change
POST/
- Access
- Public. No key needed.
- Rate limit
- 10 requests per 10 minutes
Finishes a change requested with POST /account/email, using the token from the link sent to the NEW address. Public on purpose: the single-use token is the proof, so the link works on any device.
Request body (application/json)
| Field | Type | Description |
|---|---|---|
tokenrequired | string | The token from the confirmation link sent to the new address |
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | - |
emailrequireddata.email | string (email) | The address now on the account |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Resend the verification email
POST/
- Access
- API key. Full-access keys only; not reachable by scoped keys.
- Rate limit
- 100 requests per second (the default)
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | Same fields as Message, shown earlier on this page. |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 401
UNAUTHORIZED: missing, invalid, expired or revoked credential. - 403
FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Redeem an invite code after sign-up
POST/
- Access
- API key. Full-access keys only; not reachable by scoped keys.
- Rate limit
- 10 requests per 10 minutes
For social sign-ups, or a code mistyped at registration. ok: false carries the reason. When the email is not verified yet, the credit is held (pending: true) and added on verification.
Request body (application/json)
| Field | Type | Description |
|---|---|---|
coderequired | string | -max 64 chars |
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | - |
okrequireddata.ok | boolean | - |
amountdata.amount | money | Test credit granted USD as a decimal string with exactly 6 places, e.g. "0.012500". |
pendingdata.pending | boolean | True when the credit waits for email verification |
reasondata.reason | string | Why the code was not applied |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 401
UNAUTHORIZED: missing, invalid, expired or revoked credential. - 403
FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Resend a verification email by address
POST/
- Access
- Public. No key needed.
- Rate limit
- 5 requests per hour
For users whose link expired and who cannot sign in. Always answers the same way, whether or not the account exists.
Request body (application/json)
| Field | Type | Description |
|---|---|---|
emailrequired | string (email) | - |
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | Same fields as Message, shown earlier on this page. |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Request a password reset email
POST/
- Access
- Public. No key needed.
- Rate limit
- 5 requests per hour
Always answers the same way, whether or not the account exists.
Request body (application/json)
| Field | Type | Description |
|---|---|---|
emailrequired | string (email) | - |
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | Same fields as Message, shown earlier on this page. |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Reset your password with a reset token
POST/
- Access
- Public. No key needed.
- Rate limit
- 15 requests per hour
Request body (application/json)
| Field | Type | Description |
|---|---|---|
tokenrequired | string | - |
newPasswordrequired | string | -max 128 chars |
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | Same fields as Message, shown earlier on this page. |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Change your password
POST/
- Access
- Dashboard session. API keys are refused with 403. Use a login access token.
- Rate limit
- 100 requests per second (the default)
Requires the current password. Signs out every session, including this one once its access token expires, and emails a confirmation.
Request body (application/json)
| Field | Type | Description |
|---|---|---|
currentPasswordrequired | string | - |
newPasswordrequired | string | At least 8 characters and different from the current password |
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | Same fields as Message, shown earlier on this page. |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 401
UNAUTHORIZED: missing, invalid, expired or revoked credential. - 403
FORBIDDEN: not allowed - a scoped key lacks the scope, or the endpoint is session-only. - 409
CONFLICT(or a code-specific 409): the change clashes with existing state. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
List the social login providers that are enabled
GET/
- Access
- Public. No key needed.
- Rate limit
- 100 requests per second (the default)
Response 200
| Field | Type | Description |
|---|---|---|
datarequired | object | - |
googlerequireddata.google | boolean | - |
linkedinrequireddata.linkedin | boolean | - |
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Start a social login
GET/
- Access
- Public. No key needed.
- Rate limit
- 100 requests per second (the default)
A browser navigation, not an API call. Redirects to the provider; next is a same-site path to land on afterwards.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
providerrequired | path | string | -One of google, linkedin |
next | query | string | Relative path to open after signing in, e.g. /dashboard |
Response 302
Redirect to the provider, or to /login?oauth_error=unavailable when the provider is not configured.
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 404
NOT_FOUND: no such resource on your account. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.
Finish a social login (provider callback)
GET/
- Access
- Public. No key needed.
- Rate limit
- 100 requests per second (the default)
Called by the provider after consent. Signs the browser in and redirects into the app, or to /login?oauth_error=... on failure.
Parameters
| Name | In | Type | Description |
|---|---|---|---|
providerrequired | path | string | -One of google, linkedin |
code | query | string | - |
state | query | string | - |
error | query | string | - |
Response 302
Redirect into the app when signed in, or to /login with an oauth_error reason.
Errors
- 400
VALIDATION_ERROR,INVALID_INPUTorBAD_REQUEST. ForVALIDATION_ERROR,error.detailsis an array of{ path, message }. - 404
NOT_FOUND: no such resource on your account. - 429
RATE_LIMITED: slow down and retry after theRetry-Afterseconds. - 500
INTERNAL_ERROR: unexpected failure. QuoteX-Request-Idto support.