- The token is a Basic-auth username. Every request sends
Authorization: Basic <base64(token:)>— the token as the username with an empty password, which the API ignores. There is no bearer header and no query parameter, and a wrong token answers a bare401with no body at all. - Errors come back as XML. A 401 has no body, but a 400, 403 or 404 answers
<reply><status>0</status><error_code>…</error_code><error_string>…</error_string><extra_info>…</extra_info></reply>. The plugin puts the error string and the reasons fromextra_infoin the error message, for exampleWorksnaps 400: Bad parameters in request (user_ids parameter has to be specified). - A 403 on
users.createmeans the wrong kind of token. Creating a user is documented as a privileged operation that needs a partner API token issued out of band, not an ordinary user’s, so a 403 there is expected for a normal key. Other 403s are plain permission or “operation not supported” answers; the error message says which. - XML, not JSON. Every response is
application/xml, and every create or update body must be too. The plugin has its own small reader and writer, so it parses what the API sends without adding a dependency: elements, attributes, text, CDATA, comments, the five entities and numeric references. - Responses are Rails-shaped. A collection is
<projects><project>…</project></projects>, which becomes{ projects: [...] }: the root element’s name is kept as the key, so you read the resource by name. An empty collection is a bare<projects/>and becomes[]. Ids and durations arrive as text and are coerced to numbers. - Creates and updates answer inside
<reply>. The plugin drops the envelope, soprojects.createreturns{ project: {…} }likeprojects.getdoes. - The routes carry
.xmlin the path./projects.xml,/projects/3456/tasks.xml,/me.xml. The plugin builds them as documented rather than hiding the extension, so a URL you see in the docs matches what the plugin calls. GET /me.xmlis the cheapest check. It returns the account behind the token, which verifies the credential without touching project data.- Time is Unix seconds on a 10-minute grid.
from_timestampandto_timestampare Unix seconds that must be multiples of 600.timeEntries.listalso needsuser_ids.timeEntries.createlogs offline time for yourself on a task you are assigned to; Worksnaps splits it into 10-minute entries and the call returns all of them.timeEntries.updatecan only move an entry to another task or change its comment. - Reports.
reports.projectis a time summary (or, withname: 'time_entries', the entries) for some users over at most 30 days.reports.summaryis the manager report: time per user, project, task and day across the projects you manage, by date. projects.deletearchives. The API marks the project archived and drops it fromprojects.list; nothing is erased, andprojects.updatewithstatus: 'active'restores it.
- 30 typed API operations
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
- API Key (Recommended)
No setup required yet. When you make your first request as a tenant, Corsair prompts for the API key.More: API Key
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 your projectsWhat’s next
API reference
Every
worksnaps.api.* operation with input and output types.Connect / OAuth
createLink, Hub delivery, and tenant connect flows.
Use with agents
Expose this plugin’s operations as MCP tools.