Skip to content

API Endpoints ​

OAuth Endpoints ​

Authorization Endpoint ​

GET /oauth/auth

Initiates an OAuth 2.0 authorization flow. Redirects the user to the login/consent page.

ParameterTypeRequiredDescription
response_typestringYescode for authorization code flow
client_idstringYesYour OAuth client ID
redirect_uristringYesRegistered redirect URI
scopestringYesSpace-separated list of scopes
statestringRecommendedRandom string for CSRF prevention
code_challengestringYes (PKCE)S256 code challenge
code_challenge_methodstringYes (PKCE)Must be S256

Token Endpoint ​

POST /oauth/token
Content-Type: application/x-www-form-urlencoded

Exchange an authorization code, refresh token, client credentials, or device code for an access token.

Authorization Code:

ParameterDescription
grant_typeauthorization_code
codeThe authorization code
redirect_uriMust match the original request
client_idYour client ID
client_secretYour client secret
code_verifierPKCE code verifier

Client Credentials:

ParameterDescription
grant_typeclient_credentials
client_idYour client ID
client_secretYour client secret
scopeRequested scopes

Refresh Token:

ParameterDescription
grant_typerefresh_token
refresh_tokenThe refresh token
client_idYour client ID
client_secretYour client secret

Device Code:

ParameterDescription
grant_typeurn:ietf:params:oauth:grant-type:device_code
device_codeThe device code
client_idYour client ID

Response (all grant types):

json
{
  "access_token": "eyJhbG...",
  "token_type": "Bearer",
  "expires_in": 900,
  "refresh_token": "ey...",
  "scope": "openid profile"
}

Revocation Endpoint ​

POST /oauth/revocation
Content-Type: application/x-www-form-urlencoded

Revoke an access token or refresh token. See Token Revocation for details.

ParameterDescription
tokenThe token to revoke
token_type_hintaccess_token or refresh_token
client_idYour client ID
client_secretYour client secret (confidential clients)

Introspection Endpoint ​

POST /oauth/introspection
Content-Type: application/x-www-form-urlencoded

Check whether a token is active. Returns { "active": true, ... } or { "active": false }.

ParameterDescription
tokenThe token to inspect
client_idYour client ID
client_secretYour client secret (confidential clients)

JWKS Endpoint ​

GET /oauth/jwks

Returns the JSON Web Key Set for verifying access token signatures.

Device Authorization Endpoint ​

POST /oauth/device/authorize
Content-Type: application/x-www-form-urlencoded
ParameterDescription
client_idYour client ID
scopeRequested scopes

Response:

json
{
  "device_code": "...",
  "user_code": "ABCD-1234",
  "verification_uri": "https://host/device",
  "expires_in": 600,
  "interval": 5
}

Admin Endpoints ​

All admin endpoints require authentication via Authorization: Bearer <admin_token> header (or legacy kAuth header).

Response envelope:

json
{
  "didSucceed": true,
  "data": { ... },
  "status": 200,
  "message": "optional message"
}

Auth ​

These endpoints are public (no auth required) unless noted.

MethodPathAuthDescription
POST/admin/auth/registerNoCreate a new admin account
POST/admin/auth/loginNoSign in and receive a JWT
GET/admin/auth/meYesGet current user info
POST/admin/auth/forgot-passwordNoRequest a password reset token
POST/admin/auth/reset-passwordNoReset password with token
POST/admin/auth/verify-emailNoVerify email with token
POST/admin/auth/resend-verificationYesResend verification email
POST/admin/auth/refreshYesIssue a fresh JWT
POST/admin/auth/logoutYesInvalidate all sessions
PATCH/admin/auth/profileYesUpdate name
POST/admin/auth/change-passwordYesChange password (requires current password)
PATCH/admin/auth/users/:id/deactivateYesDeactivate an admin user

Clients ​

MethodPathDescription
GET/admin/clientsList all OAuth clients
GET/admin/clients/:idGet client details with scopes
POST/admin/clientsCreate a new client
PUT/admin/clients/:idUpdate client metadata
DELETE/admin/clients/:idDeactivate a client
POST/admin/clients/:id/rotate-secretGenerate a new client secret
PUT/admin/clients/:id/scopesReplace scopes assigned to a client

Create Client body:

json
{
  "client_name": "My App",
  "redirect_uris": ["https://myapp.com/callback"],
  "grant_types": ["authorization_code", "refresh_token"],
  "token_endpoint_auth_method": "client_secret_basic",
  "application_type": "web",
  "scope_ids": [1, 3, 5]
}

Scopes ​

MethodPathDescription
GET/admin/scopesList all available scopes
GET/admin/scopes/:idGet scope details
POST/admin/scopesCreate a new scope
PUT/admin/scopes/:idUpdate a scope

Available scopes include:

ScopeDescription
openidOpenID Connect scope
profileUser profile information
projects:readRead projects
projects:writeCreate/update projects
invoices:readRead invoices
invoices:writeCreate/update invoices
time:readRead time entries
time:writeCreate/update time entries
adminFull admin access (all scopes)
readRead access to all resources
writeWrite access to all resources

See the full list in the OAuth Portal.


REST API Endpoints ​

All REST API endpoints require Authorization: Bearer <access_token>. See the Resource API and Query API guides for full details.

Special Endpoints ​

MethodPathScopeDescription
GET/api/v1/meanyCurrent user info and granted scopes
GET/api/v1/companyanyCompany information
GET/api/v1/settingsanyCompany settings
GET/api/v1/validanyValidate token, returns granted scopes

Resource CRUD ​

Standard CRUD endpoints are generated for 21 resource types. See the Resource API guide for the full list, supported methods, query parameters, and response formats.

GET    /api/v1/{resource}              # List (paginated)
GET    /api/v1/{resource}/:id          # Get by ID
POST   /api/v1/{resource}              # Create
PUT    /api/v1/{resource}/:id          # Full update
PATCH  /api/v1/{resource}/:id          # Partial update
DELETE /api/v1/{resource}/:id          # Delete
GET    /api/v1/{resource}/search?q=    # Search
GET    /api/v1/{resource}/since/:ts    # Delta sync

Query API ​

Batch queries and advanced filtering. See the Query API guide.

POST   /api/v1/query                   # Batch query (multiple models)
POST   /api/v1/query/:modelName        # Single model query
POST   /api/v1/query/:modelName/:id    # Find by ID