https://app.timelyapp.com/<workspace id>/oauth_applications), then store its client ID and secret. Timely access tokens do not expire; refresh tokens rotate on every use.
Every call is scoped to a workspace. Operations take an optional accountId; without one the plugin uses timely({ accountId }), then the account’s stored account_id, then the only workspace the token can reach. When the user belongs to several workspaces, pass accountId (from accounts.list).
What you get:
- 36 typed API operations
- 12 incoming webhook event types
Setup
1
Install
2
Add the plugin
corsair.ts
multiTenancy: true, scope calls with corsair.withTenant(id). See Quick start for KEK + Hub keys, and Multi-tenancy for account isolation.3
Choose authentication
- OAuth 2.0 (Recommended)
Open hub.corsair.dev, navigate to your project, and enter the client ID and client secret from your Timely OAuth app.More: OAuth 2.0
accountId is optional when the connected user has a single Timely workspace.4
Connect a tenant
Mint a connect link and send the tenant to it. Hub hosts the page and delivers the result to your app — see Connect / OAuth.
Example API calls
List this week’s time entriesWebhooks
Timely sends a thin reference (entity_id, entity_type, date), not the full entry. Fetch the entry with timeEntries.get. Create the Timely webhook with a secret_token and store the same value as the account’s webhook_signature: unsigned deliveries are rejected.
What’s next
API reference
Every
timely.api.* operation with input and output types.Webhooks
Event paths, payloads, and
webhookHooks examples.Connect / OAuth
createLink, Hub delivery, and tenant connect flows.
Use with agents
Expose this plugin’s operations as MCP tools.