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.
https://go.okrstool.com/api/v1- All requests must be authenticated with a Bearer API key in the
Authorizationheader. - All responses are JSON, UTF-8 encoded.
- Timestamps use ISO 8601 in UTC.
- Each key is rate-limited to 60 requests per minute.
okrs:read— list OKRs and Key Resultswrite:okrs— create or update OKRs and KRsokr-checkins:write— submit KR check-ins
cycle_id— callGET /api/v1/cycleskr_id— read the nestedkey_resultsarray onGET /api/v1/okrs
curl https://go.okrstool.com/api/v1/okrs \
-H "Authorization: Bearer okrt_your_api_key_here"# 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" }'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.
| Scope | Allows |
|---|---|
okrs:read | List OKRs with progress, status, and health. |
write:okrs | Create, update, and delete OKRs and Key Results. |
kpis:read | List KPIs with current value, target, and status. |
kpis:write | Create new KPIs and submit KPI value updates. |
okr-checkins:write | Submit Key Result check-ins. |
reviews:read | Read review cycles and shared review answers. |
Any workspace admin can create keys and grant any combination of scopes.
Authorization: Bearer okrt_your_api_key_hereRate 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.
| Header | Description |
|---|---|
Retry-After | Seconds 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.
{
"error": "rate_limit_exceeded",
"retry_after_seconds": 30
}Pagination
All list endpoints return up to 500 records per request, ordered by most recently created first.
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.
records per request, sorted by created_at desc.
Postman collection
Download the official Postman collection to start making requests in seconds — no manual setup required.
- Open Postman → Import → select the downloaded file
- Set the
api_keycollection variable to your key from Settings → API Keys - All requests are pre-configured and ready to run
Errors
All errors follow the same JSON shape so they're easy to handle in client code.
| Status | Code | Meaning |
|---|---|---|
| 400 | bad_request | The request body or parameters are malformed. |
| 401 | unauthorized | Missing or invalid API key. |
| 403 | forbidden | The key does not have the required scope. |
| 404 | not_found | The resource does not exist or is not accessible to this key. |
| 429 | rate_limit_exceeded | You exceeded 60 requests in the current minute. |
| 500 | server_error | Something went wrong on our end. Safe to retry. |
{
"error": "forbidden",
"message": "This key does not have kpis:write permission"
}OKRs
Read your organisation's OKRs and submit Key Result check-ins.
/api/v1/okrsrequiresokrs:readReturns 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.
401Invalid or missing API key.403Key is missing the okrs:read scope.
curl https://go.okrstool.com/api/v1/okrs \
-H "Authorization: Bearer okrt_your_api_key_here"[
{
"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-…"
}
]
}
]/api/v1/key-results/:id/checkinsrequiresokr-checkins:writeRecords 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').
400value is missing or not a number/yes/no/boolean, or status is invalid.404Key Result does not exist in this workspace.
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"
}'{
"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"
}/api/v1/okrs/:id/checkinsrequiresokr-checkins:writeDeprecated: 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.
400value is missing or not a number.404Key Result does not exist in this workspace.
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"
}'{
"id": "9e2b…",
"okr_id": "f4b1a2c8-…",
"key_result_id": "KR_ID",
"value": 70,
"status": "on_track",
"created_at": "2026-04-19T12:00:00Z"
}/api/v1/okrsrequireswrite:okrsCreate 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).
400title, type, or cycle_id missing or invalid.403Key is missing the write:okrs scope.
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"
}'{
"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"
}/api/v1/okrs/:idrequireswrite:okrsUpdate an existing OKR. Only the fields you include are changed. Returns the full updated OKR.
400No updatable fields provided or values invalid.404OKR does not exist in this workspace.
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"
}'{
"id": "f4b1a2c8-…",
"title": "Improve onboarding conversion (revised)",
"type": "org",
"owner_id": "u9f8e7d6-…",
"visibility": "team",
"updated_at": "2026-04-19T12:05:00Z"
}/api/v1/okrs/:idrequireswrite:okrsDelete an OKR and all its Key Results. Returns 204 with an empty body on success.
404OKR does not exist in this workspace.
curl -X DELETE https://go.okrstool.com/api/v1/okrs/OKR_ID \
-H "Authorization: Bearer okrt_your_api_key_here"(empty body)/api/v1/okrs/:id/key-resultsrequireswrite:okrsAdd 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.
400title, metric_type, start_value, or target_value missing or invalid.404OKR does not exist in this workspace.
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": "%"
}'{
"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"
}/api/v1/key-results/:idrequireswrite:okrsUpdate an existing Key Result. Only the fields you include are changed. Returns the full updated Key Result.
400No updatable fields provided or values invalid.404Key Result does not exist in this workspace.
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-…"
}'{
"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"
}/api/v1/key-results/:idrequireswrite:okrsDelete a Key Result and all its check-ins. Returns 204 with an empty body on success.
404Key Result does not exist in this workspace.
curl -X DELETE https://go.okrstool.com/api/v1/key-results/KR_ID \
-H "Authorization: Bearer okrt_your_api_key_here"(empty body)Cycles
List the OKR cycles in your workspace. Use the returned id values as cycle_id when creating OKRs via POST /api/v1/okrs.
/api/v1/cyclesrequiresokrs:readReturns 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).
401Invalid or missing API key.403Key is missing the okrs:read scope.
curl https://go.okrstool.com/api/v1/cycles \
-H "Authorization: Bearer okrt_your_api_key_here"[
{
"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"
}
]KPIs
Read tracked KPIs and post new measurement values.
/api/v1/kpisrequireskpis:readReturns up to 500 KPIs with their current value, target, unit, and computed status.
401Invalid or missing API key.403Key is missing the kpis:read scope.
curl https://go.okrstool.com/api/v1/kpis \
-H "Authorization: Bearer okrt_your_api_key_here"[
{
"id": "a812…",
"name": "Weekly Active Users",
"current": 3721,
"target": 4500,
"unit": "users",
"status": "at_risk",
"last_updated": "2026-04-01T09:30:00Z"
}
]/api/v1/kpisrequireskpis:writeCreates 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).
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.
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"
}'{
"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"
}/api/v1/kpis/:id/updatesrequireskpis:writeRecords a new KPI measurement. The previous value is captured automatically for trend tracking.
400value is missing or not a number.404KPI does not exist in this workspace.
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"
}'{
"id": "u-7c2…",
"kpi_id": "KPI_ID",
"previous_value": 3721,
"new_value": 3810,
"created_at": "2026-04-19T12:00:00Z"
}Initiatives
Manage initiatives — work items linked to OKRs and Key Results.
/api/v1/initiativesrequiresokrs:readList 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).
400Invalid query parameter (unknown status, malformed UUID).401Invalid or missing API key.403Key is missing the okrs:read scope.
curl https://go.okrstool.com/api/v1/initiatives?status=in_progress \
-H "Authorization: Bearer okrt_your_api_key_here"{
"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"
}
]
}/api/v1/initiatives/:idrequiresokrs:readFetch a single initiative by ID. Must belong to the authenticated workspace.
401Invalid or missing API key.404Initiative not found in this workspace.
curl https://go.okrstool.com/api/v1/initiatives/INIT_ID \
-H "Authorization: Bearer okrt_your_api_key_here"{
"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"
}
}/api/v1/initiativesrequireswrite:okrsCreate 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).
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.
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"
}'{
"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"
}
}/api/v1/initiatives/:idrequireswrite:okrsUpdate 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).
400Invalid field value or no fields provided.404Initiative not found in this workspace.
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"
}'{
"data": {
"id": "init-uuid",
"title": "Launch onboarding redesign",
"status": "done",
"end_date": "2026-05-10",
"...": "other fields"
}
}/api/v1/initiatives/:idrequireswrite:okrsDelete an initiative and its KR links.
401Invalid or missing API key.404Initiative not found in this workspace.
curl -X DELETE https://go.okrstool.com/api/v1/initiatives/INIT_ID \
-H "Authorization: Bearer okrt_your_api_key_here"{ "success": true }Reviews
Read review cycles and the raw answers from shared reviews.
/api/v1/review-cyclesrequiresreviews:readLists all review cycles in the workspace with the count of distinct reviewees.
403Key is missing the reviews:read scope.
curl https://go.okrstool.com/api/v1/review-cycles \
-H "Authorization: Bearer okrt_your_api_key_here"[
{
"id": "rc-2c8…",
"name": "Q2 2026 Mid-Year Review",
"status": "active",
"due_date": "2026-05-03",
"reviewee_count": 2
}
]/api/v1/reviews/:id/summaryrequiresreviews:readReturns 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.
404Review does not exist or has not been shared yet.
curl https://go.okrstool.com/api/v1/reviews/REVIEW_ID/summary \
-H "Authorization: Bearer okrt_your_api_key_here"{
"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"
}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.
Claude Desktop config
Add this block to your claude_desktop_config.json:
{
"mcpServers": {
"okrstool": {
"url": "https://go.okrstool.com/api/public/mcp",
"headers": {
"Authorization": "Bearer YOUR_API_KEY"
}
}
}
}Available tools
| Tool | Description | Parameters |
|---|---|---|
| get_okrs | List OKRs for the active cycle with progress and status | cycle_id?, status? |
| get_okr | Get a single OKR with all its Key Results | okr_id |
| create_checkin | Log a check-in on a Key Result | kr_id, value, note? |
| get_kpis | List KPIs with current values and targets | status? |
| get_cycle | Get the active cycle details and overall health | — |
| get_risks | OKRs and KRs at risk of missing their targets | severity? |
| get_insights | AI-generated insights for the organisation | — |
| get_team_performance | Team health and OKR performance summary | cycle_id? |
| search_okrs | Search OKRs and Key Results by keyword | query, cycle_id? |
Test it from the CLI
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"}'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"}
}
}'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.
- 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
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
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
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
| Value | Meaning |
|---|---|
on_track | Progress is on pace to hit the target |
at_risk | Progress is lagging but recoverable |
off_track | Progress 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
curl https://go.okrstool.com/api/v1/okrs \
-H "Authorization: Bearer okrt_your_api_key_here" \
-o okrs.jsonEach 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
curl https://go.okrstool.com/api/v1/kpis \
-H "Authorization: Bearer okrt_your_api_key_here" \
-o kpis.jsonStep 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.
- 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.
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.
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.
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
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);
}400 response. Stick to the documented enums: category ∈ acquisition | conversion | retention | revenue | custom, update_frequency ∈ weekly | monthly | quarterly, direction ∈ higher | lower.