For the complete documentation index, see llms.txt. This page is also available as Markdown.

Rhythms REST API v2

REST API v2 is the Rhythms API for third-party integrations, reporting, automation and bulk changes. It offers predictable JSON endpoints under https://api.rhythms.ai/rest/v2/ for Objectives, Key Results, Initiatives, Check-ins, Labels, Teams and Users. This article mirrors the published reference at apidocs.rhythms.ai/rest/v2, where you can also send test requests. To get a token, see Get access to the Rhythms REST API.

Basics

Base URL: https://api.rhythms.ai. All REST API v2 endpoints are prefixed with /rest/v2/.

Response format: JSON. Successful responses wrap the payload in a data object. Error responses use standard HTTP status codes with a short message.

Authentication: every request needs a Bearer token in the Authorization header. The API runs each request with the permissions of the user the token belongs to.

Authorization: Bearer ‹token›

Rate limiting

Rhythms does not publish fixed per-token rate limits today. Keep request volume reasonable — page with limit=100, use count=true instead of walking every page to get a total, and cache what you can. The API reserves 429 Too Many Requests; handle it with a back-off and retry. If you expect sustained high volume, tell support@rhythms.ai about the integration.

Pagination and counts

List endpoints support pagination through query parameters.

Parameter
Type
Default
Description

page

number

1

Page number.

limit

number

20

Records per page, maximum 100.

per_page

number

20

Alias for limit.

limit_max

number

—

Maximum records per page; used as the page size when limit is not set.

count

string

—

Set to true to include the total in data.pagy.count. Use this for totals instead of paginating through every page.

Paginated responses include metadata in data.pagy; next is the next page number, or null when there are no more pages.

Making requests

A first request

List endpoints return data.records (an array) plus data.pagy:

Single-record endpoints return data.record instead of data.records. Record fields are abbreviated above; the live docs carry the full schema.

Filtering

List endpoints accept a q parameter using bracket notation: the attribute name followed by a predicate.

Predicate
Meaning

_eq

exact match

_cont

contains (substring)

_in

value is in a list, e.g. q[current_status_in][]=behind&q[current_status_in][]=at_risk

_gteq / _lteq

greater than or equal / less than or equal — useful on dates

_present / _null

attribute is set / attribute is null

Add q[s]=‹attribute›+asc|desc to sort. The attribute before the predicate must be filterable for that endpoint; each section below lists the filterable attributes.

Paging

data.pagy.next holds the next page number, or null on the last page. Add count=true to include a total in data.pagy.count.

When authentication fails

A missing or invalid token returns 401:

A valid token whose user is not allowed to perform the action returns 403.

Going further

The live docs at apidocs.rhythms.ai/rest/v2 carry the full schema for every endpoint, let you send a real authenticated request from the browser, and let you load the API definition into an AI coding assistant such as Cursor.

API sections

REST API v2 has 7 sections and 34 operations.

Section
Operations

Checkins

5

Initiatives

5

Key Results

5

Labels

5

Objectives

5

Teams

5

Users

4

Checkins

Check-ins record progress updates, status, notes, values and labels for a goal.

Method
Path
Summary

GET

/rest/v2/checkins

List check-ins.

POST

/rest/v2/checkins

Create a check-in.

GET

/rest/v2/checkins/{id}

Get a check-in.

PUT

/rest/v2/checkins/{id}

Update a check-in.

DELETE

/rest/v2/checkins/{id}

Delete a check-in.

List check-ins

GET /rest/v2/checkins returns check-ins newest first and supports filtering and pagination.

Filterable attributes: uuid, goal_uuid, creator_uuid, checkin_date, created_at, status, value, source_type.

Create a check-in

POST /rest/v2/checkins creates a check-in for a goal with an optional value, status and note. Fields are sent at the top level of the JSON body (no wrapper object).

Field
Type
Required
Notes

goal_uuid

string

yes

UUID of the goal being checked in. (checkinable_uuid is accepted as a deprecated alias.)

timezone_offset

number

yes

Your offset from UTC in minutes, as JavaScript's getTimezoneOffset() reports it (negative east of UTC). Must be between -840 and 720.

value

number

no

Check-in value. The goal must have a metric.

status

string

no

Defaults to not_started; one of not_started, in_progress, on_track, behind, at_risk, closed, postponed.

note

string

no

Check-in note.

checkin_date

string

no

YYYY-MM-DD. Defaults to today in your timezone; cannot be in the future.

score

number

no

Score; only stored when status is closed.

progress_mode

string

no

Sets the goal's progress mode: manual, rollup or integration.

labels

array[string]

no

Label names to apply to the check-in.

Checking in on a draft goal publishes it, provided the token's user is allowed to publish it.

Get, update and delete a check-in

  • GET /rest/v2/checkins/{id} retrieves a check-in by UUID.

  • PUT /rest/v2/checkins/{id} updates value, status, note, score and labels. At least one must be provided. A score is kept only while the status is closed.

  • DELETE /rest/v2/checkins/{id} deletes a check-in. If it was the goal's latest check-in, the goal's cached status and progress are recalculated.

Goals: Objectives, Key Results and Initiatives

Objectives, Key Results and Initiatives share the same core goal fields and CRUD pattern. Each type has its own endpoint namespace.

Endpoint namespaces

Goal type
List/create path
Specific record path

Objectives

/rest/v2/objectives

/rest/v2/objectives/{id}

Key Results

/rest/v2/key_results

/rest/v2/key_results/{id}

Initiatives

/rest/v2/initiatives

/rest/v2/initiatives/{id}

{id} accepts either the goal's UUID or its short ID such as OBJ-001 or KR-014. List endpoints return published goals only, ordered by title.

Shared create fields

Used by POST /rest/v2/objectives, POST /rest/v2/key_results and POST /rest/v2/initiatives. Fields are sent at the top level of the JSON body.

Field
Type
Required
Notes

title

string

yes

Goal title.

description

string

no

Goal description.

time_period_uuid

string

yes

Time period UUID. Its dates define the allowed goal date range.

start_date

string

no

YYYY-MM-DD; must fall within the time period and be on or before end_date. Defaults to the period start.

end_date

string

no

YYYY-MM-DD; must fall within the time period and be on or after start_date. Defaults to the period end.

goal_type

string

no

Defaults to aspirational; one of aspirational, committed.

visibility

string

no

Defaults to public; one of public, limited.

team_uuids

array[string]

no

Team UUIDs; default [].

owner_uuids

array[string]

no

Owner UUIDs; default [].

labels

array[string]

no

Label names; default []. Unknown names are created when the token's user may create labels.

delegate_uuids

array[string]

no

Delegate UUIDs; default [].

metric

object

no

Metric configuration.

metric.name

string

no

Defaults to Progress.

metric.start_value

number

no

Defaults to 0.

metric.target_value

number

no

Defaults to 100.

metric.unit

string

no

One of percentage, number, dollar, euro, pound, swiss_franc. Defaults to number for Key Results and to percentage for Objectives and Initiatives — set it explicitly if you need a particular unit.

metric.metric_type

string

no

Defaults to reach; one of reach, stay_above, stay_below, stay_between.

parents

array[object]

no

Parent goal objects, not strings: {"uuid": "‹parent UUID›", "type": "‹parent type›", "is_contributing": true}. is_contributing is optional — omit it to use your workspace's OKR model default for this goal type. Default [].

visible_entities

array[object]

no

Who can see the goal when visibility is limited. Array of objects: {"entity_type": "User" | "Team", "entity_uuid": "<UUID>", "mode": "<visibility mode>"}. Default [].

Shared update fields

Used by PUT /rest/v2/objectives/{id}, PUT /rest/v2/key_results/{id} and PUT /rest/v2/initiatives/{id}. Update fields include title, description, goal_type, visibility, current_status, start_date, end_date, time_period_uuid, team_uuids, owner_uuids, labels, delegate_uuids, progress_mode, metric, parents and visible_entities. Only the fields you send are changed. Changing time_period_uuid resets omitted start and end dates to the new period's boundaries. When you resend parents, include every parent that should remain; a parent left out is unlinked, and a parent resent without is_contributing keeps its current contribution.

Shared delete options

Used by DELETE /rest/v2/objectives/{id}, DELETE /rest/v2/key_results/{id} and DELETE /rest/v2/initiatives/{id}. Deleting through the API removes the goal permanently — unlike deleting in the Rhythms app, it does not go to Trash and cannot be restored. Check the goal's children and links first.

Field
Type
Default
Notes

including_immediate_objectives

boolean

false

Also delete immediate child objectives.

including_immediate_initiatives

boolean

false

Also delete immediate child initiatives.

including_immediate_key_results

boolean

false

Also delete immediate child key results.

delete_hierarchy

boolean

false

Delete the entire hierarchy beneath the goal.

Goal list filters

The Objective, Key Result and Initiative list endpoints support filtering on uuid, type, current_status, last_checkin_date, time_period_uuid, creator_uuid and discarded_at, plus associated filters for time periods, owners, labels, ancestors, teams, child links and delegates.

Labels

Labels can be regular labels or label groups, and can be attached to OKRs and check-ins.

Method
Path
Summary

GET

/rest/v2/labels

List labels and label groups.

POST

/rest/v2/labels

Create a label.

GET

/rest/v2/labels/{id}

Get a label.

PUT

/rest/v2/labels/{id}

Update a label.

DELETE

/rest/v2/labels/{id}

Delete a label.

GET /rest/v2/labels supports filtering on uuid, name, parent_uuid and is_group.

To create or update a label, send a label wrapper object. Create accepts name (required, unique in the workspace), description, parent_uuid (the parent must be a group), is_group and color (a hex code such as #eb5757). Update accepts name, description, parent_uuid and color; send a blank parent_uuid to move a label back to the root, and a blank color to clear it. Whether a label is a group cannot be changed after creation. Creating labels requires a Rhythms Admin token.

Deleting a label also deletes its child labels.

Teams

Teams can have a parent team, owners, members, and an active or archived status.

Method
Path
Summary

GET

/rest/v2/teams

List teams.

POST

/rest/v2/teams

Create a team.

GET

/rest/v2/teams/{id}

Get a team.

PUT

/rest/v2/teams/{id}

Update a team.

DELETE

/rest/v2/teams/{id}

Delete a team.

GET /rest/v2/teams supports filtering on uuid, display_name, parent_uuid, status, is_org and depth, plus associated team membership filters.

To create or update a team, send a team wrapper object.

  • Create accepts display_name (required), description, parent_uuid, owner_uuids and member_uuids. A user listed in both arrays becomes a Team Owner.

  • Update accepts the same fields plus status, one of active or archived. Status can only be set on update, not on create. Sending owner_uuids replaces the full set of Team Owners; sending member_uuids adds the listed members.

A team can be deleted only if it has no active sub-teams and no OKR relationships.

Users

Users can be listed, created, retrieved and updated. REST API v2 has no user delete operation; deactivate a user by setting status to closed.

Method
Path
Summary

GET

/rest/v2/users

List users.

POST

/rest/v2/users

Create a user.

GET

/rest/v2/users/{id}

Get a user.

PUT

/rest/v2/users/{id}

Update a user.

GET /rest/v2/users supports filtering on uuid, display_name, status, manager_uuid and license_type, plus associated filters for direct teams, team memberships, profile fields and manager fields.

To create or update a user, send a user wrapper object.

  • Create requires email (unique in the workspace) and display_name. Optional: license_type (standard, hris_only or guest; default standard), status (active or closed; default active), manager_uuid, and profile_attributes with first_name, last_name, job_title, timezone, locale and about.

  • Update accepts display_name, avatar_url (applied only when the user has no avatar yet), status, manager_uuid, license_type and profile_attributes.

A manager_uuid must refer to an existing user, otherwise the request returns 422.

Common response codes

Code
Meaning

200

Success.

201

Created.

400

Bad Request — invalid parameters or malformed request.

401

Unauthorized — invalid or missing token, or the token's user is no longer active.

403

Forbidden — the token's user is not allowed to perform this action in Rhythms.

404

Not Found — resource does not exist.

422

Unprocessable Entity — validation error; the body explains which rule failed.

429

Too Many Requests — back off and retry.

500

Internal Server Error — unexpected server error.

Schemas

REST API v2 references 10 response schemas: label, okrs_checkin, okrs_initiative, okrs_key_result, okrs_objective, rest_v2_goal_collection_response, rest_v2_goal_response, rest_v2_user_collection_response, rest_v2_user_response and team.

Goal schemas for objectives, key results and initiatives share a common shape with fields for UUID, type, short ID, title, description, dates, goal type, time period, current metric (target, unit and metric type), owners, visible parent links with contribution percentages, creator, status, progress, visibility, data sources and discarded metadata.

Collection response schemas wrap records in data.records and can include data.pagy, data.checks and data.filters. Single-record response schemas wrap the record in data.record and can include data.checks and data.access_source.

Last updated

Was this helpful?