API · Authentication

Authentication

The Instica API uses API keys and bearer tokens for authentication. Obtain an API key from your account settings or sign in with Apple, then include it in every request.

How authentication works

The Instica API supports two authentication methods: API keys (recommended for integrations) and bearer tokens (obtained via Apple Sign In for mobile clients).

Include your credentials in the request header:

  • X-API-Key: YOUR_API_KEY — recommended for scripts, extensions, and server-to-server integrations
  • Authorization: Bearer YOUR_TOKEN — for mobile and web app sessions (obtained via Apple Sign In)

API keys persist until rotated or deleted. Bearer tokens remain valid until the user logs out or changes their password.

API key request
curl https://app.instica.com/api/v1/products/ \
  -H "X-API-Key: YOUR_API_KEY"

API keys

API keys are the recommended authentication method for integrations, scripts, and the browser extension. Create and manage keys from your account settings or via the API.

EndpointMethodDescription
/api/v1/api-keys/GETList active API keys
/api/v1/api-keys/POSTCreate a new API key
/api/v1/api-keys/{pk}/GETGet API key details
/api/v1/api-keys/{pk}/DELETEDelete an API key
/api/v1/api-keys/{pk}/rotate/POSTRotate (regenerate) an API key
/api/v1/api-usage/GETView API usage statistics

Security: API keys are shown in full only at creation time. Store the key immediately — it cannot be retrieved later. If lost, rotate the key to generate a new one.

Create an API key
curl -X POST https://app.instica.com/api/v1/api-keys/ \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "name": "My integration" }'
Using an API key
curl https://app.instica.com/api/v1/products/ \
  -H "X-API-Key: YOUR_API_KEY"
Rotate a key
curl -X POST \
  https://app.instica.com/api/v1/api-keys/1/rotate/ \
  -H "Authorization: Bearer YOUR_TOKEN"
Delete a key
curl -X DELETE \
  https://app.instica.com/api/v1/api-keys/1/ \
  -H "Authorization: Bearer YOUR_TOKEN"

# 204 No Content

Sign In with Apple

POST Apple Sign In

/api/auth/apple/

Exchange an Apple identity token for an Instica bearer token. Used by the iOS app and web clients supporting Sign In with Apple.

Request body

FieldTypeRequiredDescription
identity_tokenstringYesJWT from Apple's authentication service
authorization_codestringYesAuthorization code from Apple
userobjectNoOnly provided on first sign-in. Contains email and name (firstName, lastName).

If the Apple ID is already linked to an account, the existing account's token is returned. Otherwise, a new account is created automatically.

Request
curl -X POST https://app.instica.com/api/auth/apple/ \
  -H "Content-Type: application/json" \
  -d '{
    "identity_token": "eyJraWQiOiJ...",
    "authorization_code": "c1234...",
    "user": {
      "email": "user@privaterelay.appleid.com",
      "name": {
        "firstName": "Jane",
        "lastName": "Doe"
      }
    }
  }'
Response — 200 OK
{
  "token": "xyz789abc012...",
  "user": {
    "id": 43,
    "username": "jane_doe",
    "email": "user@privaterelay.appleid.com"
  }
}

Validate a token

GET Validate token

/api/auth/validate/

Check whether a stored token is still valid. Use this on app launch or when resuming a session.

Response fields — 200 OK

FieldTypeDescription
validbooleanAlways true when status is 200
userobjectUser profile: id, username, email

Returns 401 Unauthorized if the token has been invalidated.

Request
curl https://app.instica.com/api/auth/validate/ \
  -H "Authorization: Bearer abc123def456..."
Response — 200 OK
{
  "valid": true,
  "user": {
    "id": 42,
    "username": "your_username",
    "email": "you@example.com"
  }
}

Logout

POST Logout

/api/auth/logout/

Invalidate the current token. After logout, the token can no longer be used.

Returns 200 OK on success. Clear the token from local storage after calling this endpoint.

Request
curl -X POST https://app.instica.com/api/auth/logout/ \
  -H "Authorization: Bearer abc123def456..."
Response — 200 OK
{
  "detail": "Successfully logged out."
}

Registration — email

POST Email registration

/api/auth/register/email/

Create a new account with email and password. No phone verification required.

Request body

FieldTypeRequiredDescription
emailstringYesEmail address (normalized to lowercase, must be unique)
passwordstringYesMin 8 characters, must contain at least one letter and one number
password_confirmstringYesMust match password
full_namestringNoMax 150 characters. Auto-split into first/last name.

On success, returns 201 Created with a token and user object. The user is immediately authenticated.

Request
curl -X POST https://app.instica.com/api/auth/register/email/ \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane@example.com",
    "password": "SecurePass123",
    "password_confirm": "SecurePass123",
    "full_name": "Jane Doe"
  }'
Response — 201 Created
{
  "user": {
    "id": 44,
    "username": "jane_doe",
    "email": "jane@example.com"
  },
  "token": "new_token_here..."
}

Registration — phone (MFA)

Phone registration is a two-step process: begin (sends SMS) then verify (completes account creation).

POST Step 1: Begin

/api/auth/register/begin/

Sends a 6-digit verification code via SMS.

Request body

FieldTypeRequiredDescription
phone_numberstringYesE.164 format. 10-digit US numbers auto-prefixed with +1.
emailstringNoOptional email address
passwordstringNoOptional password for the account
full_namestringNoOptional full name

POST Step 2: Verify

/api/auth/register/verify/

Submit the 6-digit code to complete registration and receive a token.

Request body

FieldTypeRequiredDescription
signup_tokenUUIDYesToken returned from the begin step
codestringYes6-digit verification code from SMS
Step 1 — Begin
curl -X POST https://app.instica.com/api/auth/register/begin/ \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "+15551234567",
    "email": "jane@example.com",
    "full_name": "Jane Doe"
  }'
Response — 201 Created
{
  "signup_token": "a1b2c3d4-e5f6-...",
  "expires_at": "2026-02-16T12:30:00Z"
}
Step 2 — Verify
curl -X POST https://app.instica.com/api/auth/register/verify/ \
  -H "Content-Type: application/json" \
  -d '{
    "signup_token": "a1b2c3d4-e5f6-...",
    "code": "482915"
  }'
Response — 200 OK
{
  "user": {
    "id": 45,
    "username": "jane_doe",
    "email": "jane@example.com",
    "phone_verified": true,
    "email_verified": false
  },
  "token": "new_token_here..."
}

Password reset

The password reset flow uses three steps. Rate limited to 3 requests per user per hour.

POST Step 1: Request reset

/api/auth/password/reset/request/

Send a reset link to the user's email. Always returns 200 OK regardless of whether the email exists (prevents enumeration).

POST Step 2: Verify token

/api/auth/password/reset/verify/

Validate the reset token from the email link. Returns a masked email hint (e.g., a***@example.com).

POST Step 3: Confirm new password

/api/auth/password/reset/confirm/

Set the new password. Min 8 characters, must contain at least one letter and one number. Invalidates all existing tokens.

Confirm request body

FieldTypeRequiredDescription
tokenstringYesReset token from email link
passwordstringYesNew password (min 8 chars, letter + number)
password_confirmstringYesMust match password
Step 1 — Request
curl -X POST https://app.instica.com/api/auth/password/reset/request/ \
  -H "Content-Type: application/json" \
  -d '{ "email": "you@example.com" }'
Step 2 — Verify
curl -X POST https://app.instica.com/api/auth/password/reset/verify/ \
  -H "Content-Type: application/json" \
  -d '{ "token": "reset_token_from_email" }'
Step 3 — Confirm
curl -X POST https://app.instica.com/api/auth/password/reset/confirm/ \
  -H "Content-Type: application/json" \
  -d '{
    "token": "reset_token_from_email",
    "password": "NewSecurePass123",
    "password_confirm": "NewSecurePass123"
  }'

Password change

POST Change password

/api/auth/password/change/

Change password for an authenticated user. Requires the current password for verification.

Request body

FieldTypeRequiredDescription
current_passwordstringYesCurrent password (verified against stored hash)
new_passwordstringYesMin 8 characters, must contain letter + number
new_password_confirmstringYesMust match new_password
Request
curl -X POST https://app.instica.com/api/auth/password/change/ \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "current_password": "OldPass123",
    "new_password": "NewSecurePass456",
    "new_password_confirm": "NewSecurePass456"
  }'

Social account linking

POST Connect social account

/api/auth/connect-social/

Link a social provider (Apple, eBay, Discogs) to an existing Instica account.

Request body

FieldTypeRequiredDescription
tokenstringYesProvider auth token
providerstringYesapple, ebay, or discogs
Request
curl -X POST https://app.instica.com/api/auth/connect-social/ \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "provider": "apple",
    "token": "APPLE_ID_TOKEN"
  }'

Email recovery

POST Recover email via phone

/api/auth/email/recover/

Recover account email using a verified phone number. Rate limited to 5 requests per phone number per 15 minutes.

Request body

FieldTypeRequiredDescription
phone_numberstringYesPhone number associated with the account
full_namestringNoFull name for verification
Request
curl -X POST https://app.instica.com/api/auth/email/recover/ \
  -H "Content-Type: application/json" \
  -d '{
    "phone_number": "+15551234567"
  }'

Email verification

POST Request verification email

/api/auth/email-verification/request/

Sends a verification email to the authenticated user's email address.

POST Confirm verification

/api/auth/email-verification/confirm/

Confirm the email using the token from the verification email.

Confirm request body

FieldTypeRequiredDescription
tokenstringYesVerification token from email
Request verification
curl -X POST \
  https://app.instica.com/api/auth/email-verification/request/ \
  -H "Authorization: Bearer YOUR_TOKEN"
Confirm verification
curl -X POST \
  https://app.instica.com/api/auth/email-verification/confirm/ \
  -H "Content-Type: application/json" \
  -d '{ "token": "verify_token_from_email" }'

Account deactivation

POST Deactivate account

/api/v1/user/deactivate/

Deactivate the currently authenticated user's account. This action disables the account and invalidates all tokens. Only the account owner can deactivate their own account.

Warning: Account deactivation is irreversible. All active sessions and API keys are invalidated immediately. Contact support if you need to reactivate.

Request
curl -X POST \
  https://app.instica.com/api/v1/user/deactivate/ \
  -H "Authorization: Bearer YOUR_TOKEN"
Response — 200 OK
{
  "message": "Account deactivated successfully."
}

Best practices

  • Store tokens securely. Use Keychain on iOS, encrypted storage on web. Never log tokens or include them in URLs.
  • Handle 401 gracefully. When you receive a 401, attempt one silent re-validation via GET /api/auth/validate/. If it fails, redirect to sign-in while preserving user context.
  • Clear state on logout. After calling the logout endpoint, clear all cached tokens, user data, and session-scoped responses from local storage.
  • Use API keys for integrations. For server-to-server, extension, or script workflows, API keys are the recommended authentication method.
  • Never share credentials. Each integration or team member should use their own API key for auditability.