Accounts
Examples use
$SPAVIK_BASE_URLand$SPAVIK_API_KEY, set in Get started.
GET /health
Service health and its dependencies
Authentication : Public route, no authentication
Responses
| Code | Description |
|---|---|
200 | Success |
Example
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
| Code | Description |
|---|---|
200 | Success |
Example
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
| Name | In | Type | Description | |
|---|---|---|---|---|
limit | query | integer | optional | |
offset | query | integer | optional |
Responses
| Code | Description |
|---|---|
200 | Success |
401 | Authentication required, or invalid token. |
403 | This caller is not allowed to perform this action. |
Example
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
| Name | Type | Description | |
|---|---|---|---|
name | string | required | |
kind | api | admin | optional | An 'admin' key can only be created from a web session, and its prefix is sk-spv-admin-. |
expires_at | string | optional | Optional. Without it the key never expires, which is what production keys want. |
Responses
| Code | Description |
|---|---|
201 | Created (the secret is returned once and only once) |
401 | Authentication required, or invalid token. |
403 | This caller is not allowed to perform this action. |
Example
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
| Code | Description |
|---|---|
204 | Revoked |
401 | Authentication required, or invalid token. |
403 | This caller is not allowed to perform this action. |
404 | Unknown key. |
Example
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
| Name | Type | Description | |
|---|---|---|---|
grace_days | integer | optional |
Responses
| Code | Description |
|---|---|
201 | New key (the secret is returned once and only once) |
401 | Authentication required, or invalid token. |
403 | This caller is not allowed to perform this action. |
404 | Unknown key. |
409 | Key already rotated. |
Example
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
| Name | Type | Description | |
|---|---|---|---|
email | string | required |
Responses
| Code | Description |
|---|---|
200 | Success |
Example
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
| Name | Type | Description | |
|---|---|---|---|
email | string | required | |
password | string | required |
Responses
| Code | Description |
|---|---|
202 | Code sent |
401 | STAFF_LOGIN_INVALID: unknown address or wrong password. |
Example
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
| Name | Type | Description | |
|---|---|---|---|
email | string | required | |
code | string | required |
Responses
| Code | Description |
|---|---|
200 | Success |
400 | OTP_INVALID or OTP_TOO_MANY_ATTEMPTS. |
401 | STAFF_LOGIN_INVALID. |
Example
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
| Name | Type | Description | |
|---|---|---|---|
refresh_token | string | required |
Responses
| Code | Description |
|---|---|
204 | Revoked |
Example
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
| Name | Type | Description | |
|---|---|---|---|
token | string | optional | |
email | string | optional | |
code | string | optional |
Responses
| Code | Description |
|---|---|
200 | Success |
400 | Invalid link or code. |
403 | STAFF_LOGIN_REQUIRED: a staff address never signs in with a link. |
Example
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
| Code | Description |
|---|---|
200 | Success |
401 | Authentication required, or invalid token. |
403 | This caller is not allowed to perform this action. |
Example
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
| Name | Type | Description | |
|---|---|---|---|
full_name | string | required |
Responses
| Code | Description |
|---|---|
200 | Success |
401 | Authentication required, or invalid token. |
403 | This caller is not allowed to perform this action. |
Example
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
| Name | Type | Description | |
|---|---|---|---|
email | string | required |
Responses
| Code | Description |
|---|---|
204 | Deleted |
400 | Confirmation does not match. |
401 | Authentication required, or invalid token. |
403 | This caller is not allowed to perform this action. |
Example
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
| Code | Description |
|---|---|
302 | Redirect to the provider |
404 | Unknown provider. |
Example
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
| Code | Description |
|---|---|
302 | Redirect to the front end with a code |
400 | Invalid OAuth state. |
Example
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
| Name | Type | Description | |
|---|---|---|---|
code | string | required |
Responses
| Code | Description |
|---|---|
204 | Linked |
401 | Authentication required, or invalid token. |
403 | This caller is not allowed to perform this action. |
409 | Identity already linked to another account. |
Example
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
| Name | Type | Description | |
|---|---|---|---|
code | string | required |
Responses
| Code | Description |
|---|---|
200 | Success |
400 | Invalid or already used code. |
409 | An account already uses this address: link the provider from a signed-in session. |
Example
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
| Code | Description |
|---|---|
200 | Success |
Example
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
| Name | Type | Description | |
|---|---|---|---|
refresh_token | string | required |
Responses
| Code | Description |
|---|---|
200 | Success |
401 | Invalid refresh token. |
Example
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
| Code | Description |
|---|---|
200 | Success |
422 | PRIVATE_IP: private or local address, nothing to geolocate (local development and internal networks). |
503 | GeoIP unavailable. |
Example
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
| Code | Description |
|---|---|
200 | Success |
401 | Authentication required, or invalid token. |
403 | This caller is not allowed to perform this action. |
Example
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
| Name | Type | Description | |
|---|---|---|---|
name | string | required |
Responses
| Code | Description |
|---|---|
201 | Success |
401 | Authentication required, or invalid token. |
403 | This caller is not allowed to perform this action. |
Example
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
| Code | Description |
|---|---|
200 | Success |
401 | Authentication required, or invalid token. |
403 | This caller is not allowed to perform this action. |
Example
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
| Name | Type | Description | |
|---|---|---|---|
name | string | required |
Responses
| Code | Description |
|---|---|
200 | Success |
401 | Authentication required, or invalid token. |
403 | This caller is not allowed to perform this action. |
Example
curl -X PATCH "$SPAVIK_BASE_URL/v1/workspaces/{workspaceId}" \
-H 'X-API-Key: sk-spv-api-...' \
-H 'Content-Type: application/json' \
-d '{ }'