Skip to content

Accounts

Examples use $SPAVIK_BASE_URL and $SPAVIK_API_KEY, set in Get started.

GET /health

Service health and its dependencies

Authentication : Public route, no authentication

Responses

CodeDescription
200Success

Example

sh
curl -X GET "$SPAVIK_BASE_URL/health" \
  -H 'X-API-Key: sk-spv-api-...'

GET /openapi.json

API contract (this document)

Authentication : Public route, no authentication

Responses

CodeDescription
200Success

Example

sh
curl -X GET "$SPAVIK_BASE_URL/openapi.json" \
  -H 'X-API-Key: sk-spv-api-...'

GET /v1/api-keys

List the workspace keys

Authentication : API key (X-API-Key) or web session (Authorization: Bearer)

Parameters

NameInTypeDescription
limitqueryintegeroptional
offsetqueryintegeroptional

Responses

CodeDescription
200Success
401Authentication required, or invalid token.
403This caller is not allowed to perform this action.

Example

sh
curl -X GET "$SPAVIK_BASE_URL/v1/api-keys" \
  -H 'X-API-Key: sk-spv-api-...'

POST /v1/api-keys

Create an API key

Authentication : API key (X-API-Key) or web session (Authorization: Bearer)

Request body

NameTypeDescription
namestringrequired
kindapi | adminoptionalAn 'admin' key can only be created from a web session, and its prefix is sk-spv-admin-.
expires_atstringoptionalOptional. Without it the key never expires, which is what production keys want.

Responses

CodeDescription
201Created (the secret is returned once and only once)
401Authentication required, or invalid token.
403This caller is not allowed to perform this action.

Example

sh
curl -X POST "$SPAVIK_BASE_URL/v1/api-keys" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "prod",
  "kind": "api"
}'

DELETE /v1/api-keys/{keyId}

Revoke a key

Authentication : API key (X-API-Key) or web session (Authorization: Bearer)

Responses

CodeDescription
204Revoked
401Authentication required, or invalid token.
403This caller is not allowed to perform this action.
404Unknown key.

Example

sh
curl -X DELETE "$SPAVIK_BASE_URL/v1/api-keys/{keyId}" \
  -H 'X-API-Key: sk-spv-api-...'

POST /v1/api-keys/{keyId}/rotate

Replace a key without cutting the application off

Creates a twin key (same scope) and gives the old one an expiry date, seven days out by default: both work during the migration. grace_days: 0 revokes the old one immediately, for a compromised secret.

Authentication : API key (X-API-Key) or web session (Authorization: Bearer)

Request body

NameTypeDescription
grace_daysintegeroptional

Responses

CodeDescription
201New key (the secret is returned once and only once)
401Authentication required, or invalid token.
403This caller is not allowed to perform this action.
404Unknown key.
409Key already rotated.

Example

sh
curl -X POST "$SPAVIK_BASE_URL/v1/api-keys/{keyId}/rotate" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{
  "grace_days": 7
}'

POST /v1/auth/login

Start signing in with an email address

The single entry point, for everyone. Send the address and the API says what comes next: magic_link (a link and a code have been emailed, exchange them on POST /v1/auth/magic-link/verify) or password (a Spavik staff address: send the password on POST /v1/auth/login/password, then the emailed code on POST /v1/auth/login/verify).

The answer depends on the address domain only, never on whether an account exists.

Authentication : Public route, no authentication

Request body

NameTypeDescription
emailstringrequired

Responses

CodeDescription
200Success

Example

sh
curl -X POST "$SPAVIK_BASE_URL/v1/auth/login" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "{{email}}"
}'

POST /v1/auth/login/password

Staff sign-in: password

For Spavik staff addresses only. The password is checked before any code is sent. On success a six-digit code is emailed; exchange it on POST /v1/auth/login/verify.

Authentication : Public route, no authentication

Request body

NameTypeDescription
emailstringrequired
passwordstringrequired

Responses

CodeDescription
202Code sent
401STAFF_LOGIN_INVALID: unknown address or wrong password.

Example

sh
curl -X POST "$SPAVIK_BASE_URL/v1/auth/login/password" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "{{staff_email}}"
}'

POST /v1/auth/login/verify

Staff sign-in: emailed code

Authentication : Public route, no authentication

Request body

NameTypeDescription
emailstringrequired
codestringrequired

Responses

CodeDescription
200Success
400OTP_INVALID or OTP_TOO_MANY_ATTEMPTS.
401STAFF_LOGIN_INVALID.

Example

sh
curl -X POST "$SPAVIK_BASE_URL/v1/auth/login/verify" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "{{staff_email}}",
  "code": "{{otp_code}}"
}'

POST /v1/auth/logout

Revoke a refresh token

Authentication : Public route, no authentication

Request body

NameTypeDescription
refresh_tokenstringrequired

Responses

CodeDescription
204Revoked

Example

sh
curl -X POST "$SPAVIK_BASE_URL/v1/auth/logout" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{
  "refresh_token": "{{refresh_token}}"
}'

POST /v1/auth/magic-link/verify

Exchange the link or the code for tokens

Authentication : Public route, no authentication

Request body

NameTypeDescription
tokenstringoptional
emailstringoptional
codestringoptional

Responses

CodeDescription
200Success
400Invalid link or code.
403STAFF_LOGIN_REQUIRED: a staff address never signs in with a link.

Example

sh
curl -X POST "$SPAVIK_BASE_URL/v1/auth/magic-link/verify" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{
  "token": "{{magic_token}}"
}'

GET /v1/auth/me

Profile, plan and workspaces

Authentication : API key (X-API-Key) or web session (Authorization: Bearer)

Responses

CodeDescription
200Success
401Authentication required, or invalid token.
403This caller is not allowed to perform this action.

Example

sh
curl -X GET "$SPAVIK_BASE_URL/v1/auth/me" \
  -H 'X-API-Key: sk-spv-api-...'

PATCH /v1/auth/me

Update your profile

Authentication : API key (X-API-Key) or web session (Authorization: Bearer)

Request body

NameTypeDescription
full_namestringrequired

Responses

CodeDescription
200Success
401Authentication required, or invalid token.
403This caller is not allowed to perform this action.

Example

sh
curl -X PATCH "$SPAVIK_BASE_URL/v1/auth/me" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{ }'

DELETE /v1/auth/me

Permanently delete your account

Erases workspaces, models (engine side included) and keys. Confirm with your own email address.

Authentication : API key (X-API-Key) or web session (Authorization: Bearer)

Request body

NameTypeDescription
emailstringrequired

Responses

CodeDescription
204Deleted
400Confirmation does not match.
401Authentication required, or invalid token.
403This caller is not allowed to perform this action.

Example

sh
curl -X DELETE "$SPAVIK_BASE_URL/v1/auth/me" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{
  "email": "{{email}}"
}'

GET /v1/auth/oauth/{provider}

Start the OAuth sign-in (browser)

Authentication : Public route, no authentication

Responses

CodeDescription
302Redirect to the provider
404Unknown provider.

Example

sh
curl -X GET "$SPAVIK_BASE_URL/v1/auth/oauth/{provider}" \
  -H 'X-API-Key: sk-spv-api-...'

GET /v1/auth/oauth/{provider}/callback

Provider callback (browser)

Authentication : Public route, no authentication

Responses

CodeDescription
302Redirect to the front end with a code
400Invalid OAuth state.

Example

sh
curl -X GET "$SPAVIK_BASE_URL/v1/auth/oauth/{provider}/callback" \
  -H 'X-API-Key: sk-spv-api-...'

POST /v1/auth/oauth/{provider}/link

Link a provider to the signed-in account

The only path that attaches an identity to an existing account. An unknown identity never takes over an account merely because it claims its email address: a properly signed token can carry an address its bearer does not own.

Authentication : API key (X-API-Key) or web session (Authorization: Bearer)

Request body

NameTypeDescription
codestringrequired

Responses

CodeDescription
204Linked
401Authentication required, or invalid token.
403This caller is not allowed to perform this action.
409Identity already linked to another account.

Example

sh
curl -X POST "$SPAVIK_BASE_URL/v1/auth/oauth/{provider}/link" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{ }'

POST /v1/auth/oauth/exchange

Exchange the OAuth code for tokens

Authentication : Public route, no authentication

Request body

NameTypeDescription
codestringrequired

Responses

CodeDescription
200Success
400Invalid or already used code.
409An account already uses this address: link the provider from a signed-in session.

Example

sh
curl -X POST "$SPAVIK_BASE_URL/v1/auth/oauth/exchange" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{ }'

GET /v1/auth/providers

Available sign-in methods

Read this before building a sign-in screen, rather than hard-coding the buttons. A provider is only advertised when its credentials are configured: what is missing from this list cannot sign anyone in.

Authentication : Public route, no authentication

Responses

CodeDescription
200Success

Example

sh
curl -X GET "$SPAVIK_BASE_URL/v1/auth/providers" \
  -H 'X-API-Key: sk-spv-api-...'

POST /v1/auth/refresh

Renew the tokens

Authentication : Public route, no authentication

Request body

NameTypeDescription
refresh_tokenstringrequired

Responses

CodeDescription
200Success
401Invalid refresh token.

Example

sh
curl -X POST "$SPAVIK_BASE_URL/v1/auth/refresh" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{
  "refresh_token": "{{refresh_token}}"
}'

GET /v1/geoip

Geolocate the visitor (for pre-filling)

Authentication : Public route, no authentication

Responses

CodeDescription
200Success
422PRIVATE_IP: private or local address, nothing to geolocate (local development and internal networks).
503GeoIP unavailable.

Example

sh
curl -X GET "$SPAVIK_BASE_URL/v1/geoip" \
  -H 'X-API-Key: sk-spv-api-...'

GET /v1/workspaces

List your workspaces

Authentication : API key (X-API-Key) or web session (Authorization: Bearer)

Responses

CodeDescription
200Success
401Authentication required, or invalid token.
403This caller is not allowed to perform this action.

Example

sh
curl -X GET "$SPAVIK_BASE_URL/v1/workspaces" \
  -H 'X-API-Key: sk-spv-api-...'

POST /v1/workspaces

Create a workspace

Authentication : API key (X-API-Key) or web session (Authorization: Bearer)

Request body

NameTypeDescription
namestringrequired

Responses

CodeDescription
201Success
401Authentication required, or invalid token.
403This caller is not allowed to perform this action.

Example

sh
curl -X POST "$SPAVIK_BASE_URL/v1/workspaces" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{
  "name": "My mobile app"
}'

GET /v1/workspaces/{workspaceId}

Workspace details

Authentication : API key (X-API-Key) or web session (Authorization: Bearer)

Responses

CodeDescription
200Success
401Authentication required, or invalid token.
403This caller is not allowed to perform this action.

Example

sh
curl -X GET "$SPAVIK_BASE_URL/v1/workspaces/{workspaceId}" \
  -H 'X-API-Key: sk-spv-api-...'

PATCH /v1/workspaces/{workspaceId}

Rename a workspace

Authentication : API key (X-API-Key) or web session (Authorization: Bearer)

Request body

NameTypeDescription
namestringrequired

Responses

CodeDescription
200Success
401Authentication required, or invalid token.
403This caller is not allowed to perform this action.

Example

sh
curl -X PATCH "$SPAVIK_BASE_URL/v1/workspaces/{workspaceId}" \
  -H 'X-API-Key: sk-spv-api-...' \
  -H 'Content-Type: application/json' \
  -d '{ }'

Part of this documentation is generated from the OpenAPI contract.