Authentication
Log in, refresh tokens, and manage Personal Access Tokens for API access.
All API requests require authentication. Spedy supports two methods: short-lived JWT tokens obtained via login, and long-lived Personal Access Tokens for scripts and integrations.
Login
POST /api/v1/auth/loginAuthenticate with email and password to receive an access token.
Rate limit: 5 requests per minute per IP.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | User email address | |
| password | string | Yes | Password (min. 8 characters) |
| organizationSlug | string | No | Organization slug (when user belongs to multiple orgs) |
Example Request
{
"email": "[email protected]",
"password": "MySecureP@ss1"
}Example Response
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "usr_abc123",
"email": "[email protected]",
"name": "Alex",
"role": "ADMIN"
},
"organizationSlug": "acme-corp"
}The response also sets a spedy-refresh HTTP-only cookie used for refreshing the token.
Refresh Token
POST /api/v1/auth/refreshGet a new access token using the refresh cookie. Call this when your JWT expires instead of logging in again.
Rate limit: 30 requests per minute per IP.
Headers
| Header | Required | Description |
|---|---|---|
| x-org-slug | Yes | Organization slug |
| Cookie | Yes | Must include the spedy-refresh cookie from login |
Example Response
{
"accessToken": "eyJhbGciOiJIUzI1NiIs...",
"user": {
"id": "usr_abc123",
"email": "[email protected]",
"name": "Alex",
"role": "ADMIN"
},
"organizationSlug": "acme-corp"
}Logout
POST /api/v1/auth/logoutInvalidate the current session and clear the refresh cookie.
Example Response
{
"success": true
}Forgot Password
POST /api/v1/auth/forgot-passwordRequest a password reset email. Always returns success to prevent email enumeration.
Rate limit: 3 requests per 15 minutes per IP.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| string | Yes | Account email address |
Reset Password
POST /api/v1/auth/reset-passwordSet a new password using the reset token from the email.
Rate limit: 5 requests per 15 minutes per IP.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| token | string | Yes | Reset token from the email link |
| password | string | Yes | New password (min. 8 chars, must include uppercase, lowercase, number, special character) |
Personal Access Tokens
Personal Access Tokens (PATs) provide long-lived API access for scripts, CI/CD pipelines, and automations. They inherit the permissions of the user who created them.
PATs require a Pro plan subscription.
List Tokens
GET /api/v1/me/tokensReturns all active tokens for the current user.
Example Response
{
"tokens": [
{
"id": "tok_abc123",
"name": "CI Pipeline",
"lastUsedAt": "2025-03-15T10:30:00Z",
"createdAt": "2025-01-10T08:00:00Z"
}
]
}Create Token
POST /api/v1/me/tokensCreate a new Personal Access Token. The full token value is only returned once in the response -- store it securely.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | A descriptive name for the token |
Example Request
{
"name": "CI Pipeline"
}Example Response
{
"id": "tok_abc123",
"name": "CI Pipeline",
"token": "spedy_pat_abc123def456...",
"createdAt": "2025-03-20T14:00:00Z"
}Get Token
GET /api/v1/me/tokens/{tokenId}Retrieve details of a specific token (without the secret value).
Revoke Token
DELETE /api/v1/me/tokens/{tokenId}Permanently revoke a token. This action cannot be undone. Returns 204 No Content on success.