API reference
Authentication
Every request to the Repurch API carries an Authorization: Bearer header. There are two ways to acquire a Bearer token: a JWT issued by the sign-in flow, used by the partner dashboard, or a long-lived API key generated from Settings → Integrations, used by your back-end services.
Sign in with email and password
Exchange a partner admin's email and password for an access token and refresh token. If the account has two-step authentication enabled, this returns a short-lived pending token that must be exchanged at /auth/totp-login.
/v1/auth/loginRequest body
email stringrequired | The partner admin's email address. |
password stringrequired | The partner admin's password. |
Example request
curl https://api.repurch.com/v1/auth/login \
-H "Content-Type: application/json" \
-d '{
"email": "owner@furnitureco.example",
"password": "correct-horse-battery-staple"
}'Example response
{
"access_token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOjEyLCJicmFuZF9pZCI6ImZ1cm5pdHVyZS1jbyIsInJvbGVzIjpbInBhcnRuZXJfYWRtaW4iXSwiYW1yIjpbInB3ZCIsInRvdHAiXSwiZXhwIjoxNzQ5NjY0MDAwfQ.signature",
"refresh_token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.refresh.signature",
"token_type": "Bearer",
"expires_in": 3600
}Response fields
access_token string | Short-lived JWT (1 hour). Send as Authorization: Bearer on subsequent calls. |
refresh_token string | Long-lived JWT used to mint a fresh access_token without re-prompting the user. |
token_type string | Always Bearer. |
expires_in integer | Lifetime of the access_token in seconds. |
requires_totp boolean | Present and true when the account has two-step authentication enabled. In that case, access_token is absent and the pending_2fa_token below must be used to complete the challenge. |
pending_2fa_token string | Short-lived (5 minute) token. POST it to /v1/auth/totp-login together with the 6-digit code from the authenticator app. |
must_enrol_totp boolean | Present and true when the account requires two-step authentication but has not yet enrolled. In that case an access token IS issued and the next request should land on /v1/totp/enrol to complete setup. |
Errors
| Status | Code | Message |
|---|---|---|
| 400 | invalid_email | A valid email address is required. |
| 400 | missing_password | A password is required. |
| 401 | invalid_credentials | Email or password is incorrect. |
| 503 | jwt_not_configured | JWT key material is not configured on this site. |
Complete two-step authentication
Exchange a pending_2fa_token plus a 6-digit code (or a recovery code) for the full access and refresh tokens. Used immediately after /auth/login when the account has two-step authentication enabled.
/v1/auth/totp-loginRequest body
pending_2fa_token stringrequired | The pending token returned by /auth/login. |
code stringrequired | Either a 6-digit TOTP code from the authenticator app or one of the user's unused recovery codes. |
Example request
curl https://api.repurch.com/v1/auth/totp-login \
-H "Content-Type: application/json" \
-d '{
"pending_2fa_token": "eyJhbGciOiJFUzI1NiI...",
"code": "428901"
}'Example response
{
"access_token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.access.signature",
"refresh_token": "eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.refresh.signature",
"token_type": "Bearer",
"expires_in": 3600
}Response fields
access_token string | Access token with amr = ['pwd','totp'], unlocking partner admin scopes. |
refresh_token string | Long-lived refresh token. |
recovery_codes_remaining integer | Present when the caller used a recovery code or has 3 or fewer remaining. Surfaces a fresh-codes prompt in the dashboard. |
recovery_codes_warning string | Human-readable warning when recovery_codes_remaining is at or below 3. |
Errors
| Status | Code | Message |
|---|---|---|
| 401 | invalid_pending_token | Token is malformed or expired. |
| 401 | wrong_token_type | Token is not a pending_2fa token. |
| 401 | invalid_code | Code did not match TOTP or any unused recovery code. |
| 401 | code_already_used | That code was already used. Wait for a fresh one. |
| 403 | totp_not_enrolled | Account requires TOTP but is not yet enrolled. |
| 429 | totp_locked_out | Too many failed attempts. Try again in 15 minutes. |
Get the current user
Returns the authenticated user's profile, role set, and brand assignment. Useful as a token-validity ping and to populate session state on the client.
/v1/meAuthorization: Bearer …Example request
curl https://api.repurch.com/v1/me \
-H "Authorization: Bearer re_pk_..."Example response
{
"id": 42,
"email": "owner@furnitureco.example",
"display_name": "Sam Patel",
"brand_id": "furniture-co",
"brand_display_name": "Furniture Co",
"roles": [
"partner_admin"
],
"totp_enrolled": true
}Response fields
id integer | Internal user id. Stable across the user's lifetime. |
email string | Email the user signed in with. |
display_name string | Human-friendly name. Falls back to the local part of the email if not set. |
brand_id string | Slug identifying the partner workspace this user belongs to. Every scoped resource is filtered by this id. |
brand_display_name string | Friendly name for the brand, shown in the dashboard chrome. |
roles array | WordPress role names. partner_admin is the standard role for a retailer teammate. |
totp_enrolled boolean | Whether the user has completed two-step authentication enrolment. |
Errors
| Status | Code | Message |
|---|---|---|
| 401 | missing_bearer_token | No Authorization: Bearer header provided. |
| 401 | invalid_token | Token is malformed, expired, or signed with the wrong key. |
| 401 | user_not_found | User from token no longer exists. |
Set password from an invite
Public endpoint used by invitees to complete account setup. The reset key in the invite link acts as the authentication credential — no Bearer token is required. After success, the invitee signs in via /v1/auth/login.
/v1/partner/auth/set-passwordRequest body
login stringrequired | Username from the invite link. |
key stringrequired | Single-use reset key from the invite link. |
password stringrequired | New password. Minimum 12 characters. |
Example request
curl https://api.repurch.com/v1/partner/auth/set-password \
-H "Content-Type: application/json" \
-d '{
"login": "sam.patel",
"key": "Wk9zUkF2Vk5jR3Q5SmVRWg",
"password": "correct-horse-battery-staple"
}'Example response
{
"user_id": 87
}Response fields
user_id integer | Internal user id of the newly activated account. |
Errors
| Status | Code | Message |
|---|---|---|
| 400 | password_too_short | Password must be at least 12 characters. |
| 400 | invalid_link | This link is invalid or has expired. Ask your account manager to resend the invite. |
Token schemes
The same endpoints accept either kind of token. Choose the scheme that matches your use case.
Session tokens (JWT)
Short-lived JSON Web Tokens issued by /v1/auth/login. Access tokens live for one hour; refresh tokens for thirty days. JWTs carry an amr claim showing how the session was authenticated — ["pwd"] for password-only, ["pwd","totp"] for fully-elevated partner admin sessions. Use this scheme for the browser-based dashboard or any first-party human session.
API keys
Long-lived secrets generated from Settings → Integrations in the partner dashboard. Format:
re_pk_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6Pass exactly as you would a JWT — Authorization: Bearer re_pk_.... The API distinguishes keys from JWTs by the re_pk_ prefix. Use this scheme for server-to-server integrations. API keys cannot mint other API keys; that operation requires a browser session.