Developer docs

Cadynce REST API

Build integrations with Zapier, Make, n8n, or your own scripts. Every resource in Cadynce — goals, todos, issues, scorecard, meetings — is available under /api/v1 with scoped API keys and a consistent response shape.

Overview

  • Base URL: https://cadynce.app/api/v1
  • Auth: Bearer token (an API key). See Authentication.
  • Format: JSON on both request and response. Set Content-Type: application/json for writes.
  • Versioning: All endpoints live under /api/v1. Breaking changes will ship as /v2.
  • Timezone: All timestamps are ISO 8601 in UTC. Dates are YYYY-MM-DD.

Quickstart

  1. Sign in and go to Settings → API Keys. Create a key, pick your scopes, and copy it immediately — we only show the raw key once.
  2. Make your first request:
curl https://cadynce.app/api/v1/todos \
  -H "Authorization: Bearer cdn_live_..."

Create a todo:

curl -X POST https://cadynce.app/api/v1/todos \
  -H "Authorization: Bearer cdn_live_..." \
  -H "Content-Type: application/json" \
  -d '{"title":"Ship Zapier app","priority":"high"}'

Authentication

Every request must include an Authorization: Bearer <key> header. Keys start with the cdn_live_ prefix and are scoped to a single organization — an API key issued by org A cannot read or write data in org B.

Keys can be revoked at any time from the Settings page. A revoked key stops working immediately.

Scopes

Each key carries a set of scopes. Requests require the scope that matches the action — if a key doesn't have the required scope, you get a 403.

ScopeGrants
*All scopes (full access)
todos:read / todos:writeRead / mutate todos
goals:read / goals:writeRead / mutate goals
issues:read / issues:writeRead / mutate issues
scorecard:read / scorecard:writeRead / mutate scorecard metrics & entries
meetings:read / meetings:writeRead / mutate meetings
people:readRead organization members (read-only)
organization:readRead the organization record

Rate limits

Each API key is limited to 1,000 requests per hour, tracked as a sliding window. Every response carries these headers:

  • X-RateLimit-Limit — always 1000
  • X-RateLimit-Remaining — requests left in the current window
  • X-RateLimit-Reset — Unix timestamp (seconds) when the window resets

If you exceed the limit, you'll get 429 Too Many Requests with a Retry-After header (seconds to wait).

Pagination

List endpoints use opaque cursor pagination. Pass ?limit=25 (max 100) and, for subsequent pages, the next_cursor value from the previous response:

# page 1
GET /api/v1/todos?limit=50

# page 2
GET /api/v1/todos?limit=50&cursor=eyJjIjoiMjAyNi0wNC0xOVQwMDo...

When has_more is false you've reached the end and next_cursor will be null.

Errors

Errors return a consistent shape with a machine-readable code and a human-readable message. Field-level validation errors also include the offending field:

{
  "code": "invalid_field",
  "message": "priority must be one of: low, normal, high",
  "field": "priority"
}
StatusCommon codesMeaning
400invalid_body, missing_field, invalid_field, no_updatesMalformed or invalid request
401unauthorizedMissing or invalid API key
403forbiddenKey is missing the required scope
404not_foundResource doesn't exist (or isn't in your org)
429rate_limitedToo many requests — back off and retry
500db_errorServer error — safe to retry

Response envelopes

Single resource:

{ "data": { /* resource object */ } }

List:

{
  "data": [ /* ... */ ],
  "next_cursor": "eyJ...",    // null on the last page
  "has_more": true
}

Delete:

{ "deleted": true, "id": "..." }

The organization_id column is never returned — it is implicit from your API key.

Resource reference

To-Dos

/api/v1/todos

Methods

  • GET list
  • POST create
  • GET /:id
  • PATCH /:id
  • DELETE /:id

Scopes

  • todos:read
  • todos:write

Filters

  • completed=true|false

Fields

  • id
  • title
  • description
  • priority (low|normal|high)
  • due_date (YYYY-MM-DD)
  • completed
  • completed_at
  • owner_id
  • created_at

Goals

/api/v1/goals

Methods

  • GET list
  • POST create
  • GET /:id
  • PATCH /:id
  • DELETE /:id

Scopes

  • goals:read
  • goals:write

Filters

  • quarter
  • status
  • company_goal=true|false

Fields

  • id
  • title
  • description
  • status (not_started|on_track|off_track|at_risk|done)
  • quarter (e.g. "2026-Q2")
  • cadence (quarterly|monthly|annual|custom)
  • scoring_mode (milestone|okr)
  • okr_score (0–1)
  • is_stretch
  • company_goal
  • parent_goal_id
  • owner_id
  • team_id
  • created_at
  • updated_at

Issues

/api/v1/issues

Methods

  • GET list
  • POST create
  • GET /:id
  • PATCH /:id
  • DELETE /:id

Scopes

  • issues:read
  • issues:write

Filters

  • status
  • priority
  • category

Fields

  • id
  • title
  • description
  • status (open|resolved|dropped)
  • priority (low|medium|high)
  • category
  • owner_id
  • created_by
  • resolved_at
  • created_at
  • updated_at

Scorecard Metrics

/api/v1/scorecard/metrics

Methods

  • GET list
  • POST create
  • GET /:id
  • PATCH /:id
  • DELETE /:id

Scopes

  • scorecard:read
  • scorecard:write

Fields

  • id
  • title
  • goal (number)
  • goal_type (at_least|at_most|between|equal)
  • unit
  • frequency
  • active
  • owner_id
  • team_id
  • sort_order
  • created_at

Scorecard Entries

/api/v1/scorecard/entries

POST is an upsert keyed by (metric_id, week_date). Posting the same week replaces the prior value.

Methods

  • GET list
  • POST upsert (by metric_id + week_date)

Scopes

  • scorecard:read
  • scorecard:write

Filters

  • metric_id (required)
  • from (YYYY-MM-DD)
  • to (YYYY-MM-DD)

Fields

  • id
  • metric_id
  • week_date (YYYY-MM-DD)
  • value (number|null)
  • note
  • entered_by
  • created_at

Meetings

/api/v1/meetings

POST creates an empty meeting — agenda segments are not created automatically. Use the in-app meeting editor to build the agenda.

Methods

  • GET list
  • POST create
  • GET /:id
  • PATCH /:id
  • DELETE /:id

Scopes

  • meetings:read
  • meetings:write

Filters

  • status
  • meeting_type
  • from (ISO)
  • to (ISO)

Fields

  • id
  • title
  • meeting_type (weekly|quarterly|annual|one_on_one|custom)
  • scheduled_at (ISO 8601)
  • started_at
  • ended_at
  • status (scheduled|in_progress|completed|canceled)
  • team_id
  • facilitator_id
  • notes
  • recurrence_type (none|weekly|biweekly|monthly|quarterly)
  • recurrence_parent_id
  • zoom_join_url
  • created_at

People

/api/v1/people

Read-only. User management is not exposed via the public API.

Methods

  • GET list
  • GET /:id

Scopes

  • people:read

Fields

  • id
  • full_name
  • avatar_url
  • role (owner|admin|member|viewer)
  • seat (leadership|team|observer)
  • created_at

Organization

/api/v1/organization

Your API key identifies exactly one organization, so this is a singleton.

Methods

  • GET (singleton)

Scopes

  • organization:read

Fields

  • id
  • name
  • plan (free|pro)
  • plan_started_at
  • plan_ends_at
  • created_at

Need something we don't expose yet?

Email support@cadynce.app — we're building the public API out based on integration needs, and we're happy to prioritize what our customers ask for.