Traction Hub

API Documentation

The Traction Hub API allows you to programmatically read and write your data — scorecards, issues, quarterly goals, to-dos, headlines, and more.

Base URL: https://tractionhubapp.com/api.php

Authentication

The API uses Bearer token authentication. Generate an API key from the Admin panel, then include it in the Authorization header of every request.

Generating a Key

  1. Sign in as an admin and go to Admin → API Keys
  2. Click New API Key, give it a name, and optionally set an expiry
  3. Copy the key immediately — it is shown once only and never stored in plaintext

Using the Key

Pass the key in the Authorization header on every request:

POST /api.php
Content-Type: application/json
Authorization: Bearer th_live_a3f1b2c4d5e6...

Key Format

Keys are prefixed with th_live_ followed by 48 hex characters. Store keys securely — treat them like passwords.

Key Scope

Each key inherits the permissions of the admin who created it and is scoped to your company's data only.

401 Missing or invalid key Returned when no valid Bearer token is present
{ "error": "Not authenticated" }

Request Format

All API requests are POST to /api.php with a JSON body containing an action field.

POST /api.php
Content-Type: application/json
Authorization: Bearer th_live_a3f1b2c4d5e6...

{
  "action": "create_issue",
  "tenant_id": 42,
  "title": "Fix the revenue forecasting formula",
  "type": "obstacle",
  "priority": 2
}

Response Format

All responses are JSON. Successful responses include "success": true. Failures include "error" with a description.

// Success
{ "success": true, "id": 123 }

// Error
{ "error": "Title required" }

API Keys

Manage API keys programmatically. All endpoints require an existing valid Bearer token with admin permissions.

POST create_api_key Generate a new API key
FieldTypeDescription
tenant_idinteger requiredCompany ID the key belongs to
namestring requiredHuman label, e.g. Zapier integration
expires_atstring optionalExpiry date in YYYY-MM-DD. Omit for a non-expiring key.
{ "action": "create_api_key", "tenant_id": 1, "name": "Zapier" }
{ "success": true, "id": 3, "key": "th_live_a3f1b2c4..." }

⚠ The key value is returned once only. Store it immediately.

POST list_api_keys List active API keys for your company
FieldTypeDescription
tenant_idinteger requiredCompany ID
{ "success": true, "keys": [
  {
    "id": 3,
    "name": "Zapier",
    "key_prefix": "th_live_a3f1b2c4",
    "created_by_name": "Jane Smith",
    "created_at": "2026-02-28 10:00:00",
    "last_used_at": "2026-02-28 14:22:01",
    "expires_at": null
  }
]}

Note: only the first 16 characters of the key (key_prefix) are returned for identification. The full key is never retrievable after creation.

POST revoke_api_key Permanently revoke an API key
FieldTypeDescription
idinteger requiredAPI key ID
tenant_idinteger requiredCompany ID (must match the key's tenant)
{ "action": "revoke_api_key", "id": 3, "tenant_id": 1 }
{ "success": true }

Revocation is immediate and permanent. Any further request using the revoked key will receive a 401 response.

Scorecards

POST create_scorecard Create a new scorecard
FieldTypeDescription
tenant_idinteger requiredYour company ID
namestring requiredScorecard name (e.g. "Leadership Team")
descriptionstring optionalShort description
{ "action": "create_scorecard", "tenant_id": 1, "name": "Leadership Scorecard" }
{ "success": true, "id": 7 }
POST update_scorecard Update scorecard name/description
FieldTypeDescription
idinteger requiredScorecard ID
namestring requiredNew name
descriptionstring optionalNew description
POST delete_scorecard Permanently delete a scorecard and all its metrics
FieldTypeDescription
idinteger requiredScorecard ID to delete

Metrics

POST add_metric Add a metric to a scorecard
FieldTypeDescription
scorecard_idinteger requiredParent scorecard ID
namestring requiredMetric name (e.g. "New Leads")
ownerstring optionalPerson responsible
unitstring optionalUnit suffix: $, %, or custom (e.g. "hrs")
goalnumber optionalTarget value
goal_typestring optional>=, <=, or =. Default: >=
POST set_value Record a weekly value for a metric
FieldTypeDescription
metric_idinteger requiredMetric ID
week_datestring requiredMonday of the week in YYYY-MM-DD format
valuenumber|null requiredThe value to record. Send null to clear.
{ "action": "set_value", "metric_id": 14, "week_date": "2026-02-24", "value": 47 }
POST update_metric Update a metric's configuration
FieldTypeDescription
idinteger requiredMetric ID
namestring optionalNew name
ownerstring optionalNew owner name
unitstring optionalUnit suffix
goalnumber|null optionalNew goal value
goal_typestring optional>=, <=, or =
POST delete_metric Delete a metric and all its historical data
FieldTypeDescription
idinteger requiredMetric ID

Issues

POST create_issue Create a new issue
FieldTypeDescription
tenant_idinteger requiredCompany ID
titlestring requiredIssue title
descriptionstring optionalAdditional detail
typestring optionalobstacle, idea, or process
priorityinteger optional1 (low), 2 (medium), 3 (high). Default: 2
POST update_issue Update an issue's fields or status
FieldTypeDescription
idinteger requiredIssue ID
titlestring optionalNew title
statusstring optionalopen or solved
priorityinteger optional1, 2, or 3
POST delete_issue Delete an issue
FieldTypeDescription
idinteger requiredIssue ID

Quarterly Goals

POST create_rock Create a new Rock
FieldTypeDescription
tenant_idinteger requiredCompany ID
titlestring requiredRock title
owner_namestring requiredPerson owning this rock
quarterstring optionalQuarter label, e.g. 2026-Q1
due_datestring optionalDue date in YYYY-MM-DD
statusstring optionalnot_started, on_track, off_track, done
descriptionstring optionalAdditional detail
POST update_rock Update a Rock's fields or status

Same fields as create_rock plus id (required).

POST delete_rock Delete a Rock
FieldTypeDescription
idinteger requiredRock ID

To-Dos

POST create_todo Create a To-Do item
FieldTypeDescription
tenant_idinteger requiredCompany ID
titlestring requiredTask description
assigned_tostring requiredAssignee name
due_datestring optionalDue date in YYYY-MM-DD
POST update_todo Update a To-Do (including marking done)
FieldTypeDescription
idinteger requiredTo-Do ID
statusstring optionalpending or done
titlestring optionalUpdated title
assigned_tostring optionalUpdated assignee
due_datestring optionalUpdated due date
POST delete_todo Delete a To-Do
FieldTypeDescription
idinteger requiredTo-Do ID

Headlines

POST create_headline Create a headline
FieldTypeDescription
tenant_idinteger requiredCompany ID
titlestring requiredHeadline text
typestring optionalgood_news or heads_up
week_datestring optionalWeek in YYYY-MM-DD (Monday). Defaults to current week.
POST delete_headline Delete a headline
FieldTypeDescription
idinteger requiredHeadline ID

People Analyzer

POST create_person Add a person to the People Analyzer
FieldTypeDescription
tenant_idinteger requiredCompany ID
seat_namestring requiredRole/seat (e.g. "Integrator", "Sales Lead")
person_namestring requiredPerson's name
POST update_person Update a person's GWC ratings and notes
FieldTypeDescription
idinteger requiredPerson ID
gets_itstring optionalyes, no, or sometimes
wants_itstring optionalyes, no, or sometimes
capacitystring optionalyes, no, or sometimes
notesstring optionalFree-form notes
reviewed_datestring optionalDate last reviewed: YYYY-MM-DD
POST delete_person Remove a person from the analyzer
FieldTypeDescription
idinteger requiredPerson ID

Error Codes

HTTP StatusMeaning
200Success — check the success field in the body
400Unknown action or malformed request
401Missing or invalid API key
403Forbidden — insufficient permissions, or account subscription suspended
200 + errorBusiness logic error — check the error field
500Server or database error

Notes & Limits

  • All requests must be POST with Content-Type: application/json
  • API keys only have access to your own company's data
  • There are no hard rate limits currently — please be respectful of shared resources
  • IDs are integers. Always store them as integers, not strings
  • Dates should use YYYY-MM-DD format
  • Week dates must be a Monday

Questions? Contact us through the admin panel or reply to any Traction Hub email.