Todi

Developers

Connect Todix to your own tools

A simple REST API, signed webhooks and the same permissions as in the app. Assign. Talk. Done. Now in code too.

With your permissions

Every token belongs to one person and one workspace. The API shows nothing you can’t see in the app.

Instant webhooks

Task created, updated, completed; comment posted. Signed, retried and logged deliveries.

Safe defaults

Expiring tokens, scopes, 120 requests a minute, idempotent POSTs, no requests to internal networks.

How to connect

  1. Open your workspace in Todix: Integrations → API.
  2. Create a token with the permissions you need.
  3. Send your first request; add a webhook to listen for events.

Quick start

Your first request in three steps: create a token, add the header, send the request.

  1. Create an access token above and copy it.
  2. Add the Authorization: Bearer tdx_… header to every request.
  3. Send requests to https://todix.com.tr/api/v1. Answers are JSON.
# Your open tasks
curl https://todix.com.tr/api/v1/tasks?assignee=me \
  -H "Authorization: Bearer $TODIX_TOKEN"

# Create a task (safe to retry with the same Idempotency-Key)
curl -X POST https://todix.com.tr/api/v1/tasks \
  -H "Authorization: Bearer $TODIX_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1042" \
  -d '{"title":"Kargo etiketlerini yazdır","priority":"high","due_date":"2026-10-20"}'

# Smart filter: high priority, due today, assigned to me
curl -G https://todix.com.tr/api/v1/tasks \
  -H "Authorization: Bearer $TODIX_TOKEN" \
  --data-urlencode "filter=p1 & bugün & @ben"

Permissions

ScopeWhat it allows
tasks:readRead tasks · Tasks, comments, labels and members
tasks:writeWrite tasks · Create, update, complete, trash, assign, label
projects:readRead projects · Projects and their sections
projects:writeWrite projects · Create and update projects and sections
comments:writeWrite comments · Post comments in a task’s chat
webhooks:manageManage webhooks · Works for admins only
mcpAssistant connection (MCP) · For assistants like Claude and ChatGPT

Limits

  • 120 requests a minute per token. Every answer carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset; over the limit you get 429 and Retry-After.
  • Bodies are JSON, 64 KB at most. Lists are paginated: send the answer’s next_cursor back as ?cursor=.
  • Send an Idempotency-Key header with POST requests and the same request is never processed twice (24 hours).
  • Errors always look the same: { "error": { "code", "message" } }.
  • GET/api/v1/me—
  • GET/api/v1/workspaces—
  • GET/api/v1/taskstasks:read
  • POST/api/v1/taskstasks:write
  • GET/api/v1/tasks/{ref}tasks:read
  • PATCH/api/v1/tasks/{ref}tasks:write
  • DELETE/api/v1/tasks/{ref}tasks:write
  • POST/api/v1/tasks/{ref}/completetasks:write
  • POST/api/v1/tasks/{ref}/reopentasks:write
  • PUT/api/v1/tasks/{ref}/assigneestasks:write
  • PUT/api/v1/tasks/{ref}/labelstasks:write
  • GET/api/v1/tasks/{ref}/commentstasks:read
  • POST/api/v1/tasks/{ref}/commentscomments:write
  • GET/api/v1/projectsprojects:read
  • POST/api/v1/projectsprojects:write
  • GET/api/v1/projects/{id}projects:read
  • PATCH/api/v1/projects/{id}projects:write
  • GET/api/v1/projects/{id}/sectionsprojects:read
  • POST/api/v1/projects/{id}/sectionsprojects:write
  • GET/api/v1/labelstasks:read
  • POST/api/v1/labelstasks:write
  • GET/api/v1/memberstasks:read
  • GET/api/v1/webhookswebhooks:manage
  • POST/api/v1/webhookswebhooks:manage
  • GET/api/v1/webhooks/{id}webhooks:manage
  • PATCH/api/v1/webhooks/{id}webhooks:manage
  • DELETE/api/v1/webhooks/{id}webhooks:manage
  • POST/api/v1/webhooks/{id}/testwebhooks:manage
  • POST/api/v1/webhooks/{id}/rotate-secretwebhooks:manage
  • GET/api/v1/webhooks/{id}/deliverieswebhooks:manage

Verifying webhook signatures

Every request carries Todix-Signature: t=<time>, v1=<signature>. The signature is the HMAC-SHA256 of “time.body” with your signing secret. Compute it over the raw body, compare in constant time and reject requests older than 5 minutes.

import { createHmac, timingSafeEqual } from 'node:crypto'

// Express: app.post('/todix', express.raw({ type: 'application/json' }), handler)
export function verifyTodix(rawBody, header, secret, toleranceSeconds = 300) {
  const parts = Object.fromEntries(
    String(header ?? '').split(',').map((p) => p.trim().split('=')),
  )
  const t = Number(parts.t)
  if (!t || Math.abs(Date.now() / 1000 - t) > toleranceSeconds) return false
  const expected = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest()
  const given = Buffer.from(parts.v1 ?? '', 'hex')
  return given.length === expected.length && timingSafeEqual(given, expected)
}

Questions

Does the API cost extra?

No. The API and webhooks are free in every workspace, with a fair-use limit of 120 requests a minute per token.

Can I see other people’s tasks?

Only the ones you can see in the app. A token works with your permissions; only admins can manage webhooks.

What if I lose my token?

We can’t see tokens either. Revoke the old one and create a new one.