Developers

OAuth Apps & Permissions

Use OAuth 2.0 to give apps scoped access to the DoubleTime REST API and MCP server.

Connection details

OAuth clients use the issuer for discovery and request either the API or MCP resource.

Protocol support

  • OAuth 2.0 authorization code flow
  • PKCE with S256 code challenges
  • Authorization code; refresh token where enabled
  • Bearer access tokens for API and MCP requests

Issuer

https://doubletime.io

OAuth metadata, authorization, token, revoke, and registration endpoints are relative to this issuer.

Client authentication

  • No client secret for public clients using PKCE
  • Client secret with basic authentication for confidential clients
  • Client secret in the request body when basic authentication is not practical

OAuth endpoints

EndpointUse
/.well-known/oauth-authorization-server
Authorization server metadata for discovery.
/.well-known/oauth-protected-resource
Protected resource metadata for clients that discover available authorization servers.
/oauth/authorize
Starts the authorization code with PKCE flow and shows the DoubleTime approval screen.
/oauth/token
Exchanges an authorization code or refresh token for an access token.
/oauth/revoke
Revokes access or refresh tokens.
/oauth/register
Dynamic client registration for MCP clients. Developer API clients are created in DoubleTime.

Authorization code with PKCE

  1. Developer clients are registered with redirect URIs, resources, scopes, and a public or confidential client type.
  2. Authorization requests use response_type=code, client_id, redirect_uri, scope, resource, state, code_challenge, and code_challenge_method=S256.
  3. DoubleTime authenticates the user, displays the consent screen, and records the approved resources and scopes.
  4. The token endpoint exchanges the returned code for an access token using the same redirect URI and PKCE verifier.
  5. REST API and MCP calls use Authorization: Bearer <access_token> until the token expires or is revoked.

Client types

Public clients

Use PKCE and no client secret. This is the right model for browser, desktop, CLI, and mobile clients.

Confidential clients

Use a client secret when the integration has a trusted server that can keep secrets private.

MCP clients

OAuth-capable MCP clients can dynamically register for the MCP resource and request MCP-safe scopes.

Resources

OAuth requests should target the resource the integration will call. API and MCP scopes are separate so an AI client does not automatically receive API settings access.

REST API

https://doubletime.io/api

Use for custom apps and private scripts.

Scopes: Includes profile, billing, tasks, time, clients, projects, tags, rules, invoices, reports, and settings scopes.

MCP server

https://doubletime.io/mcp

Use for AI clients. settings:read and settings:write are not available to MCP clients.

Scopes: Includes mcp plus profile, billing, tasks, time, clients, projects, tags, rules, invoices, and reports scopes.

Scope dependencies

When an app requests a write or send scope, DoubleTime also requires the matching read scope.

Write scopes

Write access always depends on read access for the same scope family.

Requested

<scope-family>:write

Required

<scope-family>:read

For example, tasks:write also requires tasks:read.

Applies to: tasks, time, clients, projects, tags, rules, invoices, settings

Invoice sending

Sending an invoice also depends on invoice read access.

Requested

invoices:send

Required

invoices:read

An app that sends invoices must also be able to read the invoice being sent.

Applies to: invoices

Next steps

After an app is connected, review approved access in DoubleTime or continue to the API and MCP references for implementation details.

Review and revoke

  • Connected apps show approved OAuth clients and MCP clients for the signed-in account.
  • Revoking a grant invalidates that client access for the account.
  • Rotating a confidential client secret should be followed by updating the private integration that uses it.
  • If an app asks for more scopes than it needs, deny the request and reconfigure the client.