REST API

Call Osorik from scripts and integrations over HTTPS.

The REST API serves JSON under /v1 on the API origin. It uses the same credentials as the MCP server: a team API key or an OAuth access token.

SettingValue
Base URLhttps://api.osorik.dev/v1
Referencehttps://api.osorik.dev/v1/docs
OpenAPI 3.1 documenthttps://api.osorik.dev/v1/openapi.json

Make a request

Send the credential as a bearer token:

curl https://api.osorik.dev/v1/team \
  -H "Authorization: Bearer $OSORIK_API_KEY"

The API reference lists every endpoint with its request and response schemas, and builds example requests for you. It is generated from the OpenAPI document, so it always matches what the API serves.

Writes send a JSON body. This changes one field of a transaction and leaves the others as they are:

curl -X PATCH https://api.osorik.dev/v1/transactions/$TRANSACTION_ID \
  -H "Authorization: Bearer $OSORIK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "note": "Team offsite lunch" }'

What the API covers

AreaReadWrite
TeamProfile and your roleNone
ContactsList, search, getCreate, update
CategoriesListCreate
Bank accountsListNone
TransactionsList, filter, getCategory, note, contact, project, archive
InvoicesList, get, invoice settingsCreate, update and delete drafts
ExpensesList, filter, getUpdate details, archive
ProjectsList, getCreate, update, change status
TimeEntries, tasks, running timerLog, edit and delete entries; add tasks; start and stop the timer

Issuing, voiding and sending invoices, deleting contacts or expenses, uploading documents, connecting banks and managing members stay in the app. Your role applies: an endpoint that needs an owner or admin returns 403 for members.

Conventions

  • IDs are strings. An ID that doesn't exist in your team returns 404.
  • Amounts are decimal strings in the currency's major unit, such as "1250.00", next to an ISO 4217 currency code.
  • Dates are YYYY-MM-DD; timestamps are ISO 8601 in UTC.
  • Absent values are null, never missing.
  • PATCH changes only the fields you send. Send null to clear an optional field.
  • Creates return 201 with the new record; deletes return { "id": "…", "deleted": true }.

Pagination

List endpoints take limit (1 to 100, default 25) and cursor, and return a page:

{
  "data": [{ "id": "…" }],
  "nextCursor": "eyJ…"
}

Pass nextCursor as cursor to get the next page; it is null on the last page. A page can hold fewer than limit items before the last one, so keep going until nextCursor is null.

Errors

Every error returns a JSON body with a stable code and a readable message:

{
  "code": "API_KEY_INVALID",
  "message": "The API key is invalid or revoked."
}
StatusCodeMeaning
400INVALID_REQUESTThe request failed validation
400INVALID_CURSORThe pagination cursor is invalid or expired
400Other codesA business rule rejected the input, such as INVALID_DATE_RANGE
401API_KEY_REQUIREDNo bearer credential was sent
401API_KEY_INVALIDThe API key is invalid or revoked
401OAUTH_TOKEN_INVALIDThe access token is invalid or expired
403INSUFFICIENT_SCOPEThe credential lacks the read or write scope the endpoint needs
403*_FORBIDDENYour role can't do this, such as PROJECT_MANAGEMENT_FORBIDDEN
404NOT_FOUNDNo such endpoint
404*_NOT_FOUNDThe record doesn't exist in your team, such as INVOICE_NOT_FOUND
409Conflict codesThe record's state blocks the change, such as INVOICE_IMMUTABLE for an issued invoice
429RATE_LIMITEDToo many requests; wait for the seconds in Retry-After
500INTERNAL_ERRORSomething went wrong on our side

Discovery

GET https://api.osorik.dev/ returns an index that links the API, its OpenAPI document, the reference, and the MCP endpoint.

The site publishes an API catalog at https://osorik.dev/.well-known/api-catalog. It links the REST API's OpenAPI document and guides, and the MCP server's server card, guide, and OAuth protected resource metadata.

On this page