OKRs Tool
OKRs Tool
API Reference · v1
Back to app
Introduction

Getting started

The OKRs Tool API gives you read and write access to your workspace's OKRs, KPIs, and review summaries. Use it to wire up Slack bots, scheduled jobs, BI dashboards, or anything else that needs your team's progress data.

The API is JSON over HTTPS. Every endpoint is scoped to the organisation that owns the API key — you cannot access another workspace's data.

Base URL
https://go.okrstool.com/api/v1
  • All requests must be authenticated with a Bearer API key in the Authorization header.
  • All responses are JSON, UTF-8 encoded.
  • Timestamps use ISO 8601 in UTC.
  • Each key is rate-limited to 60 requests per minute.
Common scopes
  • okrs:read — list OKRs and Key Results
  • write:okrs — create or update OKRs and KRs
  • okr-checkins:write — submit KR check-ins
Finding the IDs you need
  • cycle_id — call GET /api/v1/cycles
  • kr_id — read the nested key_results array on GET /api/v1/okrs
Quick start
curl https://go.okrstool.com/api/v1/okrs \
  -H "Authorization: Bearer okrt_your_api_key_here"
End-to-end: cycles → OKRs → check-in
# 1. Find your active cycle id
curl https://go.okrstool.com/api/v1/cycles \
  -H "Authorization: Bearer okrt_your_api_key_here"

# 2. Read OKRs and pick a Key Result id from the
#    nested key_results array
curl https://go.okrstool.com/api/v1/okrs \
  -H "Authorization: Bearer okrt_your_api_key_here"

# 3. Submit a check-in for that Key Result
curl -X POST https://go.okrstool.com/api/v1/key-results/KR_ID/checkins \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "value": 70, "status": "on_track" }'
Security

Authentication

All requests must include an API key in the Authorization header as a Bearer token. Keys start with the okrt_ prefix and are tied to a single workspace.

Generate keys from Settings → API Keys. The full key is shown only once at creation — copy it immediately and store it somewhere safe (a password manager, a secrets vault, or your CI environment).

Keep keys server-side. Never commit them to git, never paste them into client-side JavaScript, and never share them in chat. Compromised keys can be revoked instantly from the Settings page.

Available scopes
ScopeAllows
okrs:readList OKRs with progress, status, and health.
write:okrsCreate, update, and delete OKRs and Key Results.
kpis:readList KPIs with current value, target, and status.
kpis:writeCreate new KPIs and submit KPI value updates.
okr-checkins:writeSubmit Key Result check-ins.
reviews:readRead review cycles and shared review answers.

Any workspace admin can create keys and grant any combination of scopes.

Authorization header
Authorization: Bearer okrt_your_api_key_here
Limits

Rate limits

Each API key is allowed 60 requests per minute. Limits reset at the start of every minute (UTC).

When you exceed the limit, the API returns a 429 response with a Retry-After header (in seconds) telling you when to try again.

HeaderDescription
Retry-AfterSeconds until the next request will be accepted. Returned only on 429.

For higher limits, batch your requests where possible (e.g. a single GET /okrs already returns up to 500 records) or open an issue describing your use case.

429 Response
{
  "error": "rate_limit_exceeded",
  "retry_after_seconds": 30
}

The list endpoints — GET /okrs, GET /kpis, and GET /review-cycles — each return at most 500 records per request.

If your workspace has fewer than 500 records, the full list is always returned in a single request — no pagination parameters needed.

If you have more than 500 records, contact us at support@okrstool.com. We’ll enable higher limits for your key while we ship cursor-based pagination in a future release.

Default page size
500

records per request, sorted by created_at desc.

Tools

Postman collection

Download the official Postman collection to start making requests in seconds — no manual setup required.

  1. Open Postman → Import → select the downloaded file
  2. Set the api_key collection variable to your key from Settings → API Keys
  3. All requests are pre-configured and ready to run
Error handling

Errors

All errors follow the same JSON shape so they're easy to handle in client code.

StatusCodeMeaning
400bad_requestThe request body or parameters are malformed.
401unauthorizedMissing or invalid API key.
403forbiddenThe key does not have the required scope.
404not_foundThe resource does not exist or is not accessible to this key.
429rate_limit_exceededYou exceeded 60 requests in the current minute.
500server_errorSomething went wrong on our end. Safe to retry.
Standard error shape
{
  "error": "forbidden",
  "message": "This key does not have kpis:write permission"
}
Resources

OKRs

Read your organisation's OKRs and submit Key Result check-ins.

GET/api/v1/okrsrequiresokrs:read

Returns the most recent 500 OKRs in your workspace, with computed progress, status, and a 0–100 health score derived from check-in recency, velocity, and progress gap. Each OKR also includes a nested key_results array — use the id of each Key Result to call the check-in and update endpoints.

Possible errors
  • 401Invalid or missing API key.
  • 403Key is missing the okrs:read scope.
Request
curl https://go.okrstool.com/api/v1/okrs \
  -H "Authorization: Bearer okrt_your_api_key_here"
Response · 200 OK
[
  {
    "id": "f4b1a2c8-…",
    "title": "Improve onboarding conversion",
    "type": "org",
    "owner": "Alice Nguyen",
    "progress": 0.65,
    "status": "on_track",
    "health_score": 82,
    "cycle": "Q2 2026",
    "key_results": [
      {
        "id": "kr-2c8f…",
        "title": "Lift signup → activation rate to 50%",
        "metric_type": "percentage",
        "start_value": 32,
        "current_value": 41,
        "target_value": 50,
        "progress": 0.50,
        "status": "on_track",
        "owner_id": "u9f8e7d6-…"
      }
    ]
  }
]
POST/api/v1/key-results/:id/checkinsrequiresokr-checkins:write

Records a Key Result check-in. The :id in the URL is the Key Result UUID (find it in the key_results array on GET /api/v1/okrs). Required: value (number, or 'yes'/'no'/boolean for binary KRs). Optional: comment (string), status (on_track | at_risk | off_track | blocked — defaults to on_track), blocker_note (required when status is 'blocked').

Possible errors
  • 400value is missing or not a number/yes/no/boolean, or status is invalid.
  • 404Key Result does not exist in this workspace.
Request
curl -X POST https://go.okrstool.com/api/v1/key-results/KR_ID/checkins \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "value": 70,
    "comment": "New flow shipped",
    "status": "on_track"
  }'
Response · 201 Created
{
  "id": "9e2b…",
  "okr_id": "f4b1a2c8-…",
  "key_result_id": "KR_ID",
  "value": 70,
  "status": "on_track",
  "comment": "New flow shipped",
  "blocker_note": null,
  "created_at": "2026-04-19T12:00:00Z"
}
POST/api/v1/okrs/:id/checkinsrequiresokr-checkins:write

Deprecated: use POST /api/v1/key-results/:id/checkins instead. Despite the path, the :id is the Key Result UUID, not the OKR UUID — this is what caused the rename. Behaviour is identical to the new endpoint and will continue to work.

Possible errors
  • 400value is missing or not a number.
  • 404Key Result does not exist in this workspace.
Request
curl -X POST https://go.okrstool.com/api/v1/okrs/KR_ID/checkins \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "value": 70,
    "comment": "New flow shipped",
    "status": "on_track"
  }'
Response · 200 OK
{
  "id": "9e2b…",
  "okr_id": "f4b1a2c8-…",
  "key_result_id": "KR_ID",
  "value": 70,
  "status": "on_track",
  "created_at": "2026-04-19T12:00:00Z"
}
POST/api/v1/okrsrequireswrite:okrs

Create a new OKR. Required: title (string), type (one of company, department, team — alias 'org' is also accepted for company), cycle_id (UUID — see GET /api/v1/cycles). Optional: description (string), owner_id (UUID), department_id (UUID), team_id (UUID), visibility (one of organisation, department, team — defaults to organisation).

Possible errors
  • 400title, type, or cycle_id missing or invalid.
  • 403Key is missing the write:okrs scope.
Request
curl -X POST https://go.okrstool.com/api/v1/okrs \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Improve onboarding conversion",
    "description": "Lift activation in the first 7 days",
    "type": "company",
    "cycle_id": "c1a2b3c4-…",
    "owner_id": "u9f8e7d6-…",
    "team_id": null,
    "visibility": "organisation"
  }'
Response · 201 Created
{
  "id": "f4b1a2c8-…",
  "title": "Improve onboarding conversion",
  "description": "Lift activation in the first 7 days",
  "type": "org",
  "cycle_id": "c1a2b3c4-…",
  "owner_id": "u9f8e7d6-…",
  "department_id": null,
  "team_id": null,
  "visibility": "organisation",
  "created_at": "2026-04-19T12:00:00Z"
}
PUT/api/v1/okrs/:idrequireswrite:okrs

Update an existing OKR. Only the fields you include are changed. Returns the full updated OKR.

Possible errors
  • 400No updatable fields provided or values invalid.
  • 404OKR does not exist in this workspace.
Request
curl -X PUT https://go.okrstool.com/api/v1/okrs/OKR_ID \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Improve onboarding conversion (revised)",
    "owner_id": "u9f8e7d6-…",
    "visibility": "team"
  }'
Response · 200 OK
{
  "id": "f4b1a2c8-…",
  "title": "Improve onboarding conversion (revised)",
  "type": "org",
  "owner_id": "u9f8e7d6-…",
  "visibility": "team",
  "updated_at": "2026-04-19T12:05:00Z"
}
DELETE/api/v1/okrs/:idrequireswrite:okrs

Delete an OKR and all its Key Results. Returns 204 with an empty body on success.

Possible errors
  • 404OKR does not exist in this workspace.
Request
curl -X DELETE https://go.okrstool.com/api/v1/okrs/OKR_ID \
  -H "Authorization: Bearer okrt_your_api_key_here"
Response · 204 No Content
(empty body)
POST/api/v1/okrs/:id/key-resultsrequireswrite:okrs

Add a Key Result to an OKR. Required: title (string), metric_type (one of number, percentage, currency, boolean), start_value (number), target_value (number). Optional: current_value (number — defaults to start_value), owner_id (UUID), unit (string, e.g. '%'). Stored KR status is one of on_track, at_risk, off_track, not_started — set via the check-in endpoint.

Possible errors
  • 400title, metric_type, start_value, or target_value missing or invalid.
  • 404OKR does not exist in this workspace.
Request
curl -X POST https://go.okrstool.com/api/v1/okrs/OKR_ID/key-results \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Lift signup → activation rate to 50%",
    "metric_type": "percentage",
    "start_value": 32,
    "target_value": 50,
    "current_value": 35,
    "owner_id": "u9f8e7d6-…",
    "unit": "%"
  }'
Response · 201 Created
{
  "id": "kr-2c8f…",
  "okr_id": "f4b1a2c8-…",
  "title": "Lift signup → activation rate to 50%",
  "metric_type": "percentage",
  "start_value": 32,
  "target_value": 50,
  "current_value": 35,
  "owner_id": "u9f8e7d6-…",
  "unit": "%",
  "status": "on_track",
  "created_at": "2026-04-19T12:00:00Z"
}
PUT/api/v1/key-results/:idrequireswrite:okrs

Update an existing Key Result. Only the fields you include are changed. Returns the full updated Key Result.

Possible errors
  • 400No updatable fields provided or values invalid.
  • 404Key Result does not exist in this workspace.
Request
curl -X PUT https://go.okrstool.com/api/v1/key-results/KR_ID \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Lift activation rate to 55%",
    "target_value": 55,
    "current_value": 38,
    "owner_id": "u9f8e7d6-…"
  }'
Response · 200 OK
{
  "id": "kr-2c8f…",
  "okr_id": "f4b1a2c8-…",
  "title": "Lift activation rate to 55%",
  "metric_type": "percentage",
  "start_value": 32,
  "target_value": 55,
  "current_value": 38,
  "owner_id": "u9f8e7d6-…",
  "unit": "%",
  "status": "on_track",
  "updated_at": "2026-04-19T12:05:00Z"
}
DELETE/api/v1/key-results/:idrequireswrite:okrs

Delete a Key Result and all its check-ins. Returns 204 with an empty body on success.

Possible errors
  • 404Key Result does not exist in this workspace.
Request
curl -X DELETE https://go.okrstool.com/api/v1/key-results/KR_ID \
  -H "Authorization: Bearer okrt_your_api_key_here"
Response · 204 No Content
(empty body)
Resources

Cycles

List the OKR cycles in your workspace. Use the returned id values as cycle_id when creating OKRs via POST /api/v1/okrs.

GET/api/v1/cyclesrequiresokrs:read

Returns all cycles in your workspace ordered by start_date (newest first). status is computed from today's date: active (today is between start_date and end_date inclusive), upcoming (start_date is in the future), or ended (end_date is in the past).

Possible errors
  • 401Invalid or missing API key.
  • 403Key is missing the okrs:read scope.
Request
curl https://go.okrstool.com/api/v1/cycles \
  -H "Authorization: Bearer okrt_your_api_key_here"
Response · 200 OK
[
  {
    "id": "c1a2b3c4-…",
    "name": "Q2 2026",
    "start_date": "2026-04-01",
    "end_date": "2026-06-30",
    "status": "active"
  },
  {
    "id": "c0e7…",
    "name": "Q1 2026",
    "start_date": "2026-01-01",
    "end_date": "2026-03-31",
    "status": "ended"
  }
]
Resources

KPIs

Read tracked KPIs and post new measurement values.

GET/api/v1/kpisrequireskpis:read

Returns up to 500 KPIs with their current value, target, unit, and computed status.

Possible errors
  • 401Invalid or missing API key.
  • 403Key is missing the kpis:read scope.
Request
curl https://go.okrstool.com/api/v1/kpis \
  -H "Authorization: Bearer okrt_your_api_key_here"
Response · 200 OK
[
  {
    "id": "a812…",
    "name": "Weekly Active Users",
    "current": 3721,
    "target": 4500,
    "unit": "users",
    "status": "at_risk",
    "last_updated": "2026-04-01T09:30:00Z"
  }
]
POST/api/v1/kpisrequireskpis:write

Creates a new KPI in the workspace. Required: name. Optional: description, category (one of acquisition, conversion, retention, revenue, custom — defaults to custom), group_name (free-text grouping label), owner_id (profile UUID in the same org), team_id (team UUID in the same org), current_value (number), target_value (number), unit (e.g. '%', '$', 'users'), update_frequency (weekly | monthly | quarterly — defaults to monthly), direction (higher | lower — defaults to higher).

Possible errors
  • 400Missing required field 'name', or invalid value (e.g. owner_id/team_id not in this org, unknown category, bad enum).
  • 401Invalid or missing API key.
  • 403Key is missing the kpis:write scope.
Request
curl -X POST https://go.okrstool.com/api/v1/kpis \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Weekly Active Users",
    "description": "Unique users who logged in this week",
    "category": "retention",
    "group_name": "North Star metrics",
    "current_value": 3721,
    "target_value": 4500,
    "unit": "users",
    "update_frequency": "weekly",
    "direction": "higher"
  }'
Response · 201 Created
{
  "id": "a812…",
  "organisation_id": "org-uuid",
  "name": "Weekly Active Users",
  "description": "Unique users who logged in this week",
  "owner_id": null,
  "team_id": null,
  "category": "retention",
  "group_name": "North Star metrics",
  "current_value": 3721,
  "target_value": 4500,
  "unit": "users",
  "status": "on_track",
  "update_frequency": "weekly",
  "direction": "higher",
  "last_updated_at": null,
  "created_by": "user-uuid",
  "created_at": "2026-04-30T09:30:00Z",
  "updated_at": "2026-04-30T09:30:00Z"
}
POST/api/v1/kpis/:id/updatesrequireskpis:write

Records a new KPI measurement. The previous value is captured automatically for trend tracking.

Possible errors
  • 400value is missing or not a number.
  • 404KPI does not exist in this workspace.
Request
curl -X POST https://go.okrstool.com/api/v1/kpis/KPI_ID/updates \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "value": 3810,
    "comment": "Small uptick after release"
  }'
Response · 200 OK
{
  "id": "u-7c2…",
  "kpi_id": "KPI_ID",
  "previous_value": 3721,
  "new_value": 3810,
  "created_at": "2026-04-19T12:00:00Z"
}
Resources

Initiatives

Manage initiatives — work items linked to OKRs and Key Results.

GET/api/v1/initiativesrequiresokrs:read

List initiatives in your workspace. Optional query params: status (todo, in_progress, done, blocked), priority (p0, p1, p2, p3), okr_id (UUID — filter by linked OKR), kr_id (UUID — filter by linked Key Result). Initiative responses include a 'priority' field (p0 | p1 | p2 | p3 | null).

Possible errors
  • 400Invalid query parameter (unknown status, malformed UUID).
  • 401Invalid or missing API key.
  • 403Key is missing the okrs:read scope.
Request
curl https://go.okrstool.com/api/v1/initiatives?status=in_progress \
  -H "Authorization: Bearer okrt_your_api_key_here"
Response · 200 OK
{
  "data": [
    {
      "id": "init-uuid",
      "title": "Launch onboarding redesign",
      "description": "Ship the new onboarding flow",
      "status": "in_progress",
      "start_date": "2026-04-01",
      "end_date": "2026-05-15",
      "owner_id": "user-uuid",
      "kr_id": "kr-uuid",
      "okr_id": "okr-uuid",
      "created_at": "2026-03-15T09:00:00Z",
      "updated_at": "2026-04-10T11:00:00Z"
    }
  ]
}
GET/api/v1/initiatives/:idrequiresokrs:read

Fetch a single initiative by ID. Must belong to the authenticated workspace.

Possible errors
  • 401Invalid or missing API key.
  • 404Initiative not found in this workspace.
Request
curl https://go.okrstool.com/api/v1/initiatives/INIT_ID \
  -H "Authorization: Bearer okrt_your_api_key_here"
Response · 200 OK
{
  "data": {
    "id": "init-uuid",
    "title": "Launch onboarding redesign",
    "description": "Ship the new onboarding flow",
    "status": "in_progress",
    "start_date": "2026-04-01",
    "end_date": "2026-05-15",
    "owner_id": "user-uuid",
    "kr_id": "kr-uuid",
    "okr_id": "okr-uuid",
    "created_at": "2026-03-15T09:00:00Z",
    "updated_at": "2026-04-10T11:00:00Z"
  }
}
POST/api/v1/initiativesrequireswrite:okrs

Create an initiative. Required: title. Optional: description, status (todo | in_progress | done | blocked, default todo), priority (p0 | p1 | p2 | p3 — null/omitted means no priority), start_date (YYYY-MM-DD), end_date (YYYY-MM-DD), owner_id (member UUID in this org), okr_id (UUID — informational), kr_id (UUID — links the initiative to a Key Result).

Possible errors
  • 400Missing title, invalid status, or referenced owner/okr/kr does not belong to this org.
  • 401Invalid or missing API key.
  • 403Key is missing the write:okrs scope.
Request
curl -X POST https://go.okrstool.com/api/v1/initiatives \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Launch onboarding redesign",
    "description": "Ship the new onboarding flow",
    "status": "in_progress",
    "start_date": "2026-04-01",
    "end_date": "2026-05-15",
    "owner_id": "user-uuid",
    "kr_id": "kr-uuid"
  }'
Response · 201 Created
{
  "data": {
    "id": "init-uuid",
    "title": "Launch onboarding redesign",
    "description": "Ship the new onboarding flow",
    "status": "in_progress",
    "start_date": "2026-04-01",
    "end_date": "2026-05-15",
    "owner_id": "user-uuid",
    "kr_id": "kr-uuid",
    "okr_id": "okr-uuid",
    "created_at": "2026-04-30T09:30:00Z",
    "updated_at": "2026-04-30T09:30:00Z"
  }
}
PUT/api/v1/initiatives/:idrequireswrite:okrs

Update an initiative. All fields are optional; provide at least one. Updatable fields include title, description, status, priority (p0 | p1 | p2 | p3 | null), start_date, end_date, owner_id, kr_id. Passing kr_id replaces the existing KR link (pass null to clear).

Possible errors
  • 400Invalid field value or no fields provided.
  • 404Initiative not found in this workspace.
Request
curl -X PUT https://go.okrstool.com/api/v1/initiatives/INIT_ID \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "done",
    "end_date": "2026-05-10"
  }'
Response · 200 OK
{
  "data": {
    "id": "init-uuid",
    "title": "Launch onboarding redesign",
    "status": "done",
    "end_date": "2026-05-10",
    "...": "other fields"
  }
}
DELETE/api/v1/initiatives/:idrequireswrite:okrs

Delete an initiative and its KR links.

Possible errors
  • 401Invalid or missing API key.
  • 404Initiative not found in this workspace.
Request
curl -X DELETE https://go.okrstool.com/api/v1/initiatives/INIT_ID \
  -H "Authorization: Bearer okrt_your_api_key_here"
Response · 200 OK
{ "success": true }
Resources

Reviews

Read review cycles and the raw answers from shared reviews.

GET/api/v1/review-cyclesrequiresreviews:read

Lists all review cycles in the workspace with the count of distinct reviewees.

Possible errors
  • 403Key is missing the reviews:read scope.
Request
curl https://go.okrstool.com/api/v1/review-cycles \
  -H "Authorization: Bearer okrt_your_api_key_here"
Response · 200 OK
[
  {
    "id": "rc-2c8…",
    "name": "Q2 2026 Mid-Year Review",
    "status": "active",
    "due_date": "2026-05-03",
    "reviewee_count": 2
  }
]
GET/api/v1/reviews/:id/summaryrequiresreviews:read

Returns the raw question/answer pairs from a shared review. Only reviews that have been shared (status: shared) are accessible — drafts return 404. We intentionally return raw answers rather than a curated summary so you can run your own AI summarisation downstream.

Possible errors
  • 404Review does not exist or has not been shared yet.
Request
curl https://go.okrstool.com/api/v1/reviews/REVIEW_ID/summary \
  -H "Authorization: Bearer okrt_your_api_key_here"
Response · 200 OK
{
  "review_id": "REVIEW_ID",
  "employee": "Sarah Chen",
  "cycle": "Q2 2026 Mid-Year Review",
  "type": "self",
  "status": "shared",
  "answers": [
    {
      "question": "What went well this cycle?",
      "answer": "Shipped the onboarding redesign on time"
    },
    {
      "question": "What are your growth areas?",
      "answer": "Delegation and prioritisation"
    }
  ],
  "shared_at": "2026-04-19T12:00:00Z"
}
AI Assistants

MCP Server

Connect OKRs Tool to Claude, Cursor, and any MCP-compatible AI assistant via a single endpoint. The Model Context Protocol (MCP) lets LLMs read OKRs, KPIs, risks, and check in on Key Results on your behalf.

Connection URL
https://go.okrstool.com/api/public/mcp
Authentication uses the same Bearer API key as the REST API. Generate one in Settings → API Keys. Requires the Expand plan or the API Access add-on.

Claude Desktop config

Add this block to your claude_desktop_config.json:

json
{
  "mcpServers": {
    "okrstool": {
      "url": "https://go.okrstool.com/api/public/mcp",
      "headers": {
        "Authorization": "Bearer YOUR_API_KEY"
      }
    }
  }
}

Available tools

ToolDescriptionParameters
get_okrsList OKRs for the active cycle with progress and statuscycle_id?, status?
get_okrGet a single OKR with all its Key Resultsokr_id
create_checkinLog a check-in on a Key Resultkr_id, value, note?
get_kpisList KPIs with current values and targetsstatus?
get_cycleGet the active cycle details and overall health
get_risksOKRs and KRs at risk of missing their targetsseverity?
get_insightsAI-generated insights for the organisation
get_team_performanceTeam health and OKR performance summarycycle_id?
search_okrsSearch OKRs and Key Results by keywordquery, cycle_id?

Test it from the CLI

List tools
curl -X POST https://go.okrstool.com/api/public/mcp \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"method":"tools/list"}'
Call a tool
curl -X POST https://go.okrstool.com/api/public/mcp \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "method":"tools/call",
    "params":{
      "name":"get_okrs",
      "arguments":{"status":"at_risk"}
    }
  }'
Recipes

Guides

End-to-end patterns for the most common API workflows.

Push OKR progress from an external system

This guide shows how to use the API to sync OKR progress from an external source — for example, a BI tool, a product analytics platform, or a spreadsheet pipeline.

What you’ll need
  • An API key with okrs:read and okr-checkins:write scopes
  • The Key Result IDs you want to update (fetched in step 1)

Step 1 — Fetch your OKRs and Key Result IDs

Request
curl https://go.okrstool.com/api/v1/okrs \
  -H "Authorization: Bearer okrt_your_api_key_here"

Each OKR in the response includes an id field. Note the id of the Key Result you want to update — you’ll use it in step 2.

Step 2 — Post a check-in to a Key Result

Request
curl -X POST https://go.okrstool.com/api/v1/okrs/KR_ID/checkins \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "value": 82,
    "comment": "Pulled from analytics pipeline — weekly active users up 12%",
    "status": "on_track"
  }'

Step 3 — Automate with a scheduled job

Python
import requests

API_KEY = "okrt_your_api_key_here"
KR_ID = "your-kr-uuid"

def push_progress(value: float, comment: str, status: str):
    response = requests.post(
        f"https://go.okrstool.com/api/v1/okrs/{KR_ID}/checkins",
        headers={"Authorization": f"Bearer {API_KEY}"},
        json={"value": value, "comment": comment, "status": status}
    )
    response.raise_for_status()
    return response.json()

push_progress(82, "Weekly sync from analytics pipeline", "on_track")

Status values

ValueMeaning
on_trackProgress is on pace to hit the target
at_riskProgress is lagging but recoverable
off_trackProgress is significantly behind target

Pull OKR health data into a BI tool

Use this pattern to extract OKR health data into Power BI, Tableau, Looker, or any BI tool that can consume a REST API or JSON file.

Step 1 — Fetch OKRs

Request
curl https://go.okrstool.com/api/v1/okrs \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -o okrs.json

Each record includes progress (0–1 float), status, health_score (0–100), owner, cycle, and type. These fields map cleanly to BI dimensions and measures.

Step 2 — Fetch KPIs

Request
curl https://go.okrstool.com/api/v1/kpis \
  -H "Authorization: Bearer okrt_your_api_key_here" \
  -o kpis.json

Step 3 — Load into your BI tool

  • Power BI: Web connector → paste the endpoint URL → authenticate with the API key as a header
  • Tableau: Web Data Connector or JSON file import
  • Looker / Metabase: Custom API connector or JSON dataset

Generate OKRs and KPIs with AI and sync via API

Combine an LLM (ChatGPT, Claude, Gemini, or your own model) with the OKRs Tool API to turn a strategic plan into structured OKRs and KPIs inside your workspace — no manual entry required.

What you’ll need
  • An API key with okrs:write and kpis:write scopes
  • Your strategic plan, OKR draft, or annual goals as text
  • An AI tool you can prompt (web UI or API)

Step 1 — Prompt the AI to draft structured OKRs and KPIs

Paste your strategy doc into ChatGPT or Claude and ask for structured JSON. A prompt like the one below produces output that maps directly to the API field names.

Prompt
You are an OKR coach. From the strategic plan below, produce JSON with two arrays:

1. "okrs": each item has { title, type ("company"|"department"|"team"), key_results: [{ title, metric_type, start_value, target_value, unit }] }
2. "kpis":  each item has { name, description, category ("acquisition"|"conversion"|"retention"|"revenue"|"custom"), update_frequency ("weekly"|"monthly"|"quarterly"), direction ("higher"|"lower"), target_value, unit }

Return only valid JSON. No prose, no markdown fences.

Strategic plan:
<paste your plan here>

Step 2 — Find the IDs you need (cycle, owner)

For OKRs you’ll need a cycle_id. Fetch your active cycles with GET /api/v1/cycles and copy the id of the cycle you want the new goals to land in. Owner UUIDs come from your org’s profiles — pass them as owner_id when creating each KPI.

Request
curl https://go.okrstool.com/api/v1/cycles \
  -H "Authorization: Bearer okrt_your_api_key_here"

Step 3 — Create each KPI from the AI output

Loop over the kpis array and POST each one. The same pattern applies to OKRs via POST /api/v1/okrs.

Node.js
const response = await fetch('https://go.okrstool.com/api/v1/kpis', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer okrt_your_api_key_here',
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({
    name: 'Member Retention Rate',
    description: 'Percentage of members who renew year-over-year',
    category: 'custom',
    owner_id: 'your-owner-uuid',
    update_frequency: 'quarterly',
    direction: 'higher',
    target_value: 85,
    unit: '%'
  })
});

const kpi = await response.json();
console.log('Created KPI:', kpi.id);

Step 4 — Bulk import from a JSON file

Node.js
import fs from 'node:fs';

const API_KEY = 'okrt_your_api_key_here';
const BASE = 'https://go.okrstool.com/api/v1';

const plan = JSON.parse(fs.readFileSync('./ai-output.json', 'utf8'));

for (const kpi of plan.kpis) {
  const res = await fetch(`${BASE}/kpis`, {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${API_KEY}`,
      'Content-Type': 'application/json'
    },
    body: JSON.stringify(kpi)
  });
  if (!res.ok) {
    console.error('Failed', kpi.name, await res.text());
    continue;
  }
  const created = await res.json();
  console.log('✓', created.name, created.id);
}
Tip: Always review the AI’s output before posting it. LLMs occasionally invent categories or units that don’t match the accepted enum values — the API will reject those with a 400 response. Stick to the documented enums: category ∈ acquisition | conversion | retention | revenue | custom, update_frequency ∈ weekly | monthly | quarterly, direction ∈ higher | lower.