makerble
API Reference v2.0.0

Makerble API

The Makerble API gives you programmatic access to your CRM and impact measurement data — contacts, projects, surveys, cases, outcomes, and more.

PropertyValue
Base URLhttps://makerble.com/api/v2
Staging URLhttps://staging.makerble.com/api/v2
Mock URL{{HOST}}/mock
ProtocolHTTPS · JSON · REST
AuthToken-based headers — X-User-Email + X-User-Token
Specopenapi.yaml · OpenAPI 3.0.3
Security

Authentication

Obtain a token by calling POST /users/sign_in. Tokens are long-lived and do not expire — each user has one fixed token.

Pass both headers on every authenticated request:

HeaderValue
X-User-EmailYour Makerble account email address
X-User-TokenYour authentication token from POST /users/sign_in
ℹ Multi-user integrations: If you need activity attributed to specific users, authenticate separately per user. A single Organisation Admin token is fine when attribution to a single admin is acceptable.
POST
/users/sign_in
Authenticate — obtain a token

Submit your email and password to receive your authentication token. Use this token in the X-User-Token header on all subsequent requests.

Request body (form-urlencoded)
FieldTypeDescription
user[email] string required Your Makerble email address
user[password] string required Your Makerble password
Responses
200Returns user_id, email, and authentication_token
401Invalid credentials
Reference

Pagination

All list endpoints support cursor-free offset pagination. The maximum per_page is 200.

ParameterTypeDefaultMaxDescription
pageinteger1—Page number
per_pageinteger10200Records per page
last_sync_datetimestring——ISO 8601 datetime — return only records updated after this value. Useful for incremental sync.
✓ All paginated responses wrap results in: { page, page_size, page_count, total_count, data: [] }
Reference

Terminology

Makerble uses different terms in the front-end UI and the API. The API uses the back-end terms listed below.

Front-end (UI)API (back-end)
OrganisationCharity
ContactBeneficiary
Contact Bio FormBeneficiary Category
SurveyStory Category
Survey CampaignProject Story Category
Survey Response / Timeline UpdateStory
Activity / Engagement trackerChange (stage: activity / participation)
Achievement / Choice / Numerical trackerIndicator (type: binary / scale / value)
Dropdown / List fieldRatio Set
Answer ChoiceSub Ratio
Case FormCustom Field Category
Developer tools

Mock server

A Prism-powered mock server is running alongside these docs. It reads the OpenAPI spec and returns realistic example responses — safe to call without touching any real Makerble data.

⬡

Mock server is live

Use this base URL in place of https://makerble.com/api/v2 for safe testing:

/mock
ℹ The mock server enforces authentication headers. Pass any non-empty values for X-User-Email and X-User-Token to receive 200 responses rather than 401s.
Example curl request to the mock
curl {{HOST}}/mock/beneficiary_types   -H "X-User-Email: test@example.com"   -H "X-User-Token: mock-token"
Core resource

Organisations

Organisations (called Charities in the API) are the top-level entity. Each Organisation owns one or more Projects, and all data ultimately belongs to an Organisation.

GET
/charities/{id}
Get a single Organisation
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Organisation ID
Responses
200Charity record with id, name, timestamps
401Not authenticated
404Not found
Core resource

Projects

Every Story and Case on Makerble belongs to a Project. A Project belongs to a single Organisation. Users hold one of three roles per Project: Editor (Manager), Reporter (Changemaker), or Observer (Analyst).

GET
/projects
List all Projects
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number (default 1)
per_page
query
integer Records per page (default 10, max 200)
last_sync_datetime
query
string ISO 8601 — return only records updated after this
Responses
200Paginated list of Projects
401Not authenticated
GET
/projects/{id}
Get a single Project
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Project ID
Responses
200Project record
401Not authenticated
404Not found
POST
/projects/add_colleague.json
Add users to a Project
Requires authentication
Grant one or more users a role on a Project. A user can hold Editor, Reporter, and Observer simultaneously. Pass user IDs in role_data[].editor_ids, reporter_ids, or observer_ids.
Responses
200Users added successfully
401Not authenticated
422Validation failed
GET
/project_results
Get Results Canvas figures for Projects
Requires authentication
Returns the figures on each Project's Results Canvas (the Results panel on a Project page), one entry per tracker, for the Projects you can view. Activity and Engagement trackers (Changes) give times_recorded and contacts; Achievement trackers (Binary Indicators) give times_recorded and contacts_achieved; Choice trackers (Scale Indicators) give answers with a count and contacts per Sub Ratio; Numerical trackers (Value Indicators) give total and average_per_contact. times_recorded counts records, not people; contacts counts distinct Contacts tagged. anonymous_count is what was recorded with no Contact tagged. target, target_deadline and percent_of_target appear when the Project has a target.
Parameters
NameTypeDescription
project_ids
query
integer[] Projects to include, as project_ids[]=619 or a JSON array string. Defaults to every Project you can view
start_date
query
string First Story date to include, YYYY-MM-DD. Omit both dates for all time
end_date
query
string Last Story date to include, YYYY-MM-DD
tracker_types
query
string[] Any of activity, engagement, achievement, choice, numerical, as an array or comma-separated list. Defaults to all
group_by
query
string project or month: adds a groups array to each tracker (empty months included)
page
query
integer Page number (default 1)
per_page
query
integer Trackers per page (default 10, max 200)
Responses
200Paginated trackers, plus start_date, end_date and project_ids
401Not authenticated
422Invalid project_ids, date, tracker_types, group_by or per_page
Core resource

Users

Platform users with login credentials. Creating users requires a separate API Key — request one at api-key-request@makerble.com.

GET
/users
List all Users
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
last_sync_datetime
query
string ISO 8601 incremental sync
Responses
200Paginated list of Users
401Not authenticated
GET
/users/{id}
Get a single User
Requires authentication
Parameters
NameTypeDescription
id
path
integer required User ID
Responses
200User record
404Not found
POST
/users
Create a new User
Requires an auth_code API Key. Password must be 8+ chars with at least one number, special character, and capital letter.
Responses
200User created — returns id and email
422Validation failed (check password requirements)
Core resource

Contacts

Contacts (Beneficiaries in the API) are the people your organisation works with. Each Contact belongs to an Organisation and can be enrolled in multiple Projects. Custom fields are defined per Contact Bio Form.

✓ Workflow tip: Call GET /beneficiary_types to get the beneficiary_type_id (1=Person, 2=Object, 3=Organisation, 4=Animal) and GET /custom_fields to discover custom field IDs before creating a Contact.
GET
/beneficiaries
List all Contacts
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
charity_id
query
integer Filter to Contacts in this Organisation
project_id
query
integer Filter to Contacts enrolled in this Project
last_sync_datetime
query
string ISO 8601 incremental sync
Responses
200Paginated list of Contacts including custom fields
401Not authenticated
GET
/beneficiaries/{id}
Get a single Contact
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Contact ID
Responses
200Full Contact profile with all custom fields
404Not found
POST
/beneficiaries
Create a Contact
Requires authentication
Required fields: beneficiary.name, beneficiary.owner_id (User ID of the record owner). Submit custom field values as custom_fields: {"field_id": "value"}.
Responses
200Contact created
422Validation failed (name and owner_id are required)
GET
/beneficiaries/impact_box_data
Get Impact Box data (Progress Trackers per Contact)
Requires authentication
Returns the data shown in the Progress Trackers box on a Contact Profile — total impact progress attributed to each Contact across all Changes and Indicators.
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
Responses
200Aggregated metric progress per Contact
GET
/beneficiary_types
List Contact Types
Requires authentication
Responses
200Person (1), Object (2), Organisation (3), Animal (4)
GET
/project_beneficiaries
List Project–Contact associations
Requires authentication
Parameters
NameTypeDescription
project_ids
query
integer[] Only include these projects (project_ids[]=12&project_ids[]=34, or a JSON array string). Never widens access beyond the projects you can see.
page
query
integer Page number
per_page
query
integer Records per page
Responses
200Join table records: project_id and beneficiary_id (the Contact) for each link
422project_ids is not an array of integers
Schema

Contact Bio Forms

Contact Bio Forms (Beneficiary Categories in the API) define the custom fields available when creating or editing a Contact. Use these endpoints to discover field IDs before calling POST /beneficiaries.

GET
/beneficiary_categories
List all Contact Bio Forms
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
Responses
200Paginated list of forms
GET
/beneficiary_categories/{id}
Get a single Contact Bio Form
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Form ID
Responses
200Form schema
404Not found
GET
/custom_fields
List custom field definitions
Requires authentication
Parameters
NameTypeDescription
beneficiary_category_ids[]
query
integer Filter by Contact Bio Form ID (repeat for multiple)
page
query
integer Page number
per_page
query
integer Records per page
Responses
200Field definitions with IDs, names, and types
Core resource

Cases

Cases are structured records for a specific Contact within a Project. Each Case has a Case Owner (creator) and optional Case Workers. Case fields are defined by a Case Form (Custom Field Category).

✓ Workflow tip: Call GET /custom_field_categories to discover field definition IDs before creating a Case.
GET
/cases
List all Cases
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
last_sync_datetime
query
string ISO 8601 incremental sync
Responses
200Paginated list of Cases
POST
/cases
Create a Case
Requires authentication
Required: project_id, beneficiary_id. Submit case form values in custom_field_categories_definition: {field_definition_id: value}.
Responses
200Case created
422Validation failed
GET
/custom_field_categories
List Case Forms (field schemas)
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
Responses
200Case Form schemas with field definition IDs
GET
/projects_beneficiaries_cases
List Project–Contact–Case associations
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
Responses
200Join table records
Surveys & Stories

Surveys

Surveys (Story Categories in the API) are the form templates used to create Stories. A Survey must be deployed as a Survey Campaign (Project Story Category) before Stories can be created with it in a Project.

⚠ Always call GET /story_categories/:id before posting a Story. It returns the survey's fields, Indicator IDs, Outcome IDs, and valid Sub Ratio IDs — all of which are required in the Story payload.
GET
/story_categories
List all Surveys
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
Responses
200Paginated list of Surveys
GET
/story_categories/{id}
Get a Survey with full field detail
Requires authentication
Returns all questions in order (current_fields), the choice type (single/multiple) for each Scale Indicator (scale_indicator_choices), and scoring bands (verdict_data).
Parameters
NameTypeDescription
id
path
integer required Survey ID
Responses
200Survey with current_fields, scale_indicator_choices, and verdict_data
404Not found
GET
/story_categories/{id}/verdicts
Get verdict scores for a Survey Campaign
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Survey ID
project_id
query
integer required Project the Survey Campaign belongs to
page
query
integer Page number
Responses
200Total points per Contact per submission, grouped by beneficiary
GET
/project_story_categories
List Survey Campaigns
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
Responses
200Surveys deployed to specific Projects
GET
/project_story_categories/{id}/survey_waves
List the Waves of a Survey Campaign
Requires authentication
Use a Wave's id as send_survey_wave_id when generating survey links.
Parameters
NameTypeDescription
id
path
integer required Survey Campaign (Project Story Category) ID
page
query
integer Page number
per_page
query
integer Records per page (max 200)
Responses
200Waves (id, name, priority) in priority order; empty if the Survey Campaign doesn't use Waves
404Survey Campaign not found
POST
/project_story_categories/{id}/survey_links
Generate personal survey links (without sending)
Requires authentication
Generates the same personal links as the Send Survey page, but sends nothing: share the returned survey_url yourself. At most 200 contacts and email addresses per request. A use_once link stops working after one response; an evergreen link stays active.
Parameters
NameTypeDescription
id
path
integer required Survey Campaign (Project Story Category) ID
beneficiary_ids
body
integer[] Contacts in the Survey Campaign's Project
emails
body
string[] Email addresses, matched to an existing Contact of the organisation or creating one. No email is sent.
send_survey_wave_id
body
integer Wave, from the Waves endpoint
link_expiry
body
string use_once (default) or evergreen
is_anonymised
body
boolean Default false
Responses
201send_survey_id and data: one link per Contact with survey_url, survey_token, link_expiry, expired
403Not a Project Editor or Organisation Editor
404Survey Campaign not found
422Contacts outside the Project (invalid_beneficiary_ids), over 200 recipients, no recipients, or an unavailable Wave
GET
/project_story_categories/{id}/survey_links
List personal survey links
Requires authentication
Use it to reuse a Contact's existing link. A use_once link that has been answered has expired: true.
Parameters
NameTypeDescription
id
path
integer required Survey Campaign (Project Story Category) ID
beneficiary_id
query
integer Only this Contact's links
send_survey_wave_id
query
integer Only links for this Wave
page
query
integer Page number
per_page
query
integer Records per page (max 200)
last_sync_datetime
query
string ISO 8601 incremental sync
Responses
200Paginated list of links
403Not a Project Editor or Organisation Editor
404Survey Campaign not found
Surveys & Stories

Stories

Stories are the primary content format on Makerble — they capture text, media, and progress towards Changes and Indicators, and can be tagged to Contacts. Every Story belongs to a Project and is created using a Survey.

Story timestamps: actual_created_at = Date Posted (database time) · created_at = Date Happened (user-selected, can be backdated) · updated_at = Date Edited.

GET
/stories
List all Stories
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
last_sync_datetime
query
string ISO 8601 incremental sync
Responses
200Paginated list of Stories with custom fields and beneficiary IDs
GET
/stories/{id}
Get a single Story
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Story ID
Responses
200Full Story with custom_fields, case_ids, story_indicator_beneficiaries, story_changes, verdict_scores
404Not found
POST
/stories
Create a Story
Requires authentication
Creates a Story tagged to zero, one, or multiple Contacts. Required: story.project_id, story.story_category_id, story.story_group: "change_created", story.story_format: "old".

Use story_indicator_beneficiaries for indicator responses, story_changes for metric totals, and custom_fields for survey text/date/time fields.

For binary indicators: include binray_indicator_value: "on" if ticked — omit the record entirely if not ticked. Activity Changes cannot be tagged to individual Contacts.
Responses
200Story created
422Validation failed
POST
/draft_stories
Save an Answer In Progress (draft Story)
Requires authentication
Saves a partly completed survey response as an Answer In Progress (draft Story) for a colleague to review, finish and publish in Makerble. Use it instead of POST /stories when a person should check the response first.

Send story.project_id, story.story_category_id and story.text, plus optional story.event_id, beneficiaries (Contact IDs), story_privacy and custom_fields.

Allowed for the Project's editors, reporters and observers, the organisation's editors and reporters, and the workers and managers of story.event_id when that Event belongs to the Project. Anyone else gets 403, as does a story.charity_id that isn't the Project's organisation.
Responses
201Saved. Returns draft_story_id
403No permission for this Project or organisation
422Validation failed
GET
/stories/story_category_response
Get Stories with full survey response detail
Requires authentication
Parameters
NameTypeDescription
story_category_id
query
integer Filter by Survey
project_ids[]
query
integer Filter by Project ID (repeat for multiple)
start_date
query
string YYYY-MM-DD — stories on or after this date
end_date
query
string YYYY-MM-DD — stories on or before this date
Responses
200Stories enriched with named Indicators, Changes, and Custom Field values — ideal for reporting
GET
/stories/{id}/attachments
Get attachments for a Story
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Story ID
Responses
200Paginated media attachments
Surveys & Stories

Story Metrics

Sub-resources that record per-story metric progress. Filter by story_id on any of these endpoints to get all metric data for a specific Story.

GET
/story_changes
List Story Changes
Requires authentication
Parameters
NameTypeDescription
story_id
query
integer Filter to a specific Story
page
query
integer Page number
Responses
200Per-story metric totals for Activity and Participation Changes
GET
/story_change_beneficiaries
List Story Change Beneficiaries
Requires authentication
Only applies to Participation type Changes (not Activity).
Parameters
NameTypeDescription
page
query
integer Page number
Responses
200Per-Contact Participation Change records
GET
/story_indicators
List Story Indicators
Requires authentication
Parameters
NameTypeDescription
story_id
query
integer Filter to a specific Story
page
query
integer Page number
Responses
200Total indicator progress logged per Story
GET
/story_indicator_beneficiaries
List Story Indicator Beneficiaries
Requires authentication
Parameters
NameTypeDescription
story_id
query
integer Filter to a specific Story
page
query
integer Page number
Responses
200Per-Contact indicator responses — one record per Contact per Indicator per Story
GET
/story_beneficiaries
List Story Beneficiaries
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
Responses
200Direct Contact-to-Story tagging records
Audit & compliance

Versions

Versions are the audit trail behind the Manage Versions page: every time a Contact is created or edited, a Version records who did it, when, and a full snapshot of every field at that moment. Only Contacts are versioned so far.

Visible to Charity Editors (any Contact in their Organisation) and Project Editors (Contacts in at least one of their Projects). Anything else returns 404. user_name is System when no signed-in user made the change, e.g. a CSV import.

GET
/versions
List a Contact's Versions (audit trail)
Requires authentication
Parameters
NameTypeDescription
record_type
query
string required Contact (the only type for now)
record_id
query
integer required Contact (Beneficiary) ID
page
query
integer Page number
per_page
query
integer Records per page (default 10, max 200)
last_sync_datetime
query
string ISO 8601 — only Versions created after this
Responses
200Paginated Versions, newest first, plus the record's name and whether it has been deleted
404Not found, or not visible to you
GET
/versions/{id}
Get a single Version with the full record snapshot
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Version ID
Responses
200The Version, including full_object — every field as saved at that moment
404Not found, or not visible to you
Impact framework

Changes

Changes are custom KPIs (Activity and Participation trackers). They appear in Progress Panel columns 1 and 2. Activity Changes are numerical metrics; Participation Changes track attendance and can tag individual Contacts.

GET
/changes
List all Changes
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
last_sync_datetime
query
string ISO 8601 incremental sync
Responses
200Paginated list of Changes with stage (activity/participation)
Impact framework

Indicators

Indicators are linked to Outcomes and appear in Progress Panel columns 3–5. Three types: Scale (multiple-choice using a Ratio Set), Binary (tickbox), Value (numerical).

GET
/indicators
List all Indicators
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
include_public_library
query
boolean Also include Indicators from the public library shared by all organisations (default false)
Responses
200Paginated list with indicator_type (scale/binary/value). Only Indicators the user can see: their own and their organisations'
GET
/indicators/{id}
Get a single Indicator
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Indicator ID
include_public_library
query
boolean Allow a public-library Indicator from another organisation to be returned (default false)
Responses
200Full Indicator detail including ratio_set_id, default_question
404Not found, or not visible to the user
GET
/scale_indicator_choices
Get Scale Indicator choices
Requires authentication
Parameters
NameTypeDescription
story_category_id
query
integer Filter by Survey
indicator_id
query
integer Filter by Indicator
Responses
200Choice type (single_choice/multiple_choice) per Scale Indicator
GET
/outcome_indicators
List Outcome–Indicator pairings
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
Responses
200Join table — use to find outcome_id for story indicator responses
Impact framework

Outcomes

Outcomes are the top-level impact categories. Progress is tracked via Indicators, not Outcomes directly. Each Outcome has a stage (short/medium/long-term) that determines which Progress Panel column its Indicators appear in.

GET
/outcomes
List all Outcomes
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
Responses
200Paginated list with title, icon, stage (short_term/medium_term/long_term)
GET
/outcomes/{id}
Get a single Outcome
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Outcome ID
Responses
200Outcome record
404Not found
Impact framework

Framework Sets

A Framework Set groups Impact Frameworks (template in the API) into one thing an organisation reports its contribution towards. For example, the 17 SDG Impact Frameworks form the set "UN Sustainable Development Goals"; others are TOMs, a funder's outcomes framework or an organisation's own strategy. Each set names its two levels, e.g. Goal › Target: level 1 is an Impact Framework and level 2 an Outcome inside it.

availability decides who can use a set: platform (every organisation; created by System Access users), network (every organisation in a Network; created by that Network's admins) or charity (one organisation; created by its organisation admins).

✓ Workflow tip: List the sets an organisation can already use before creating one. To make an organisation's own Indicators count towards a set, link them to its Outcomes with POST /framework_links. A set whose value_source is set_values uses the Financial Value it defines for each Outcome (financial_values) instead of the organisation's own.
GET
/framework_sets
List the Framework Sets an organisation can use
Requires authentication
Parameters
NameTypeDescription
charity_id
query
integer required The Organisation ID; the user must belong to it
page
query
integer Page number
per_page
query
integer Records per page
last_synced_datetime
query
string ISO 8601 incremental sync
Responses
200Paginated live sets available to the organisation, plus drafts the user can edit
403The user doesn't belong to the Organisation
404Unknown Organisation
GET
/framework_sets/{id}
Get a Framework Set
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Framework Set ID
Responses
200The set, with frameworks in order and financial_values
404Not found, or not available to the user
POST
/framework_sets
Create a Framework Set
Requires authentication
Body: charity_id, name, availability, network_id, level1_singular, level1_plural, level2_singular, level2_plural, value_source, version_label, supersedes_id, status, frameworks: [{template_id, short_code, colour, text_colour}] in order, and new_frameworks: [name] to create new Impact Frameworks.
Responses
201Framework Set created
403The user may not create a set with this availability
404Unknown Organisation
422Validation failed, e.g. no name or no Impact Frameworks
PATCH
/framework_sets/{id}
Update a Framework Set
Requires authentication
Same body as create; only the fields sent change. frameworks (when sent) replaces the ordered list; financial_values: [{outcome_id, financial_value_id}] replaces the Financial Value chosen for each Outcome.
Parameters
NameTypeDescription
id
path
integer required Framework Set ID
Responses
200Framework Set updated
403The user can't edit this set
404Not found, or not available to the user
422Validation failed
GET
/framework_links
List an organisation's Linked indicators
Requires authentication
Parameters
NameTypeDescription
charity_id
query
integer required The Organisation ID; the user must belong to it
page
query
integer Page number
per_page
query
integer Records per page
last_synced_datetime
query
string ISO 8601 incremental sync
Responses
200Paginated links with indicator_name, outcome_title, project_ids and all_projects
403The user doesn't belong to the Organisation
POST
/framework_links
Link an Indicator to an Outcome in a Framework Set
Requires authentication
Body: charity_id, indicator_id, outcome_id, project_ids (empty: every project). Linking again with more projects adds them to the existing link.
Responses
201The Linked indicator
403Not an organisation admin
422Not one of the organisation's Indicators or projects, an Outcome outside the sets it can use, or already linked
DELETE
/framework_links/{id}
Remove a Linked indicator
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Linked indicator ID
charity_id
query
integer required The Organisation ID
Responses
204Removed
403Not an organisation admin
404Not one of the organisation's links
Impact framework

Cohort Trackers

A Cohort Tracker is a metric that counts the Contacts in a Project or Album who meet a set of Contact Filter criteria, e.g. "Children attending 75%+". It is placed in an Impact Scorecard column like other metrics and targeted with a number of Contacts to reach. Every tracker counts only members of the Project or Album it is placed on: membership is ever_enrolled (anyone whose status History shows them Enrolled at any time) or currently_enrolled.

✓ Workflow tip: Check criteria with POST /cohort_trackers/preview, create the tracker, then place it on a Project with POST /cohort_trackers/{id}/projects/{project_id}. Albums pick it up from their Projects.
GET
/cohort_trackers
List an Organisation's Cohort Trackers
Requires authentication
Parameters
NameTypeDescription
charity_id
query
integer required The Organisation ID
page
query
integer Page number
per_page
query
integer Records per page
last_sync_datetime
query
string ISO 8601 incremental sync
Responses
200Paginated list of Cohort Trackers
403No editor or reporter role in the Organisation
GET
/cohort_trackers/{id}
Get a Cohort Tracker
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Cohort Tracker ID
Responses
200The tracker, with usage and names_projects_or_albums
404Not found, or another Organisation's
POST
/cohort_trackers/preview
Preview Cohort Tracker criteria
Requires authentication
Body: charity_id, cohort_tracker: {criteria, membership}. criteria takes any key the Contacts page's Filters sidebar sends. project_ids, bundle_ids, narrow_bundle_ids, projects_states_hash, project_beneficiary_states, project_story_category_ids, attendance_rate, distance_travelled, indicator_comparisons and indicator_sub_ratios_hash follow the Project or Album and the reporting period; the other sections (e.g. group_ids, age_from) apply to the Contacts' current details. Keys no filter reads are dropped.
Responses
200count of matching Contacts and the normalised criteria
422An unknown membership
POST
/cohort_trackers
Create a Cohort Tracker
Requires authentication
Body: cohort_tracker: {charity_id, name, description, membership, criteria}.
Responses
201Cohort Tracker created
403Not an editor or reporter of the Organisation
422Validation failed
PATCH
/cohort_trackers/{id}
Update a Cohort Tracker
Requires authentication
Only the fields sent change. Changes apply everywhere the tracker is used.
Parameters
NameTypeDescription
id
path
integer required Cohort Tracker ID
Responses
200Cohort Tracker updated
403Not an Organisation editor or the reporter who created it
422Validation failed
DELETE
/cohort_trackers/{id}
Delete a Cohort Tracker
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Cohort Tracker ID
Responses
204Deleted
422Still used on a Project, Album or Scorecard Template
POST
/cohort_trackers/{id}/projects/{project_id}
Add a Cohort Tracker to a Project
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Cohort Tracker ID
project_id
path
integer required Project ID
column
query
string required activities, engagement, potential, behaviour or growth
target
query
integer One-off target: a number of Contacts to reach
Responses
201Placed: {cohort_tracker_id, project_id, column, target}
403Can't edit the Project's metrics
422Unknown column, or already on the Project
GET
/cohort_trackers/{id}/projects/{project_id}
Get a Cohort Tracker's targets on a Project
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Cohort Tracker ID
project_id
path
integer required Project ID
Responses
200{cohort_tracker_id, project_id, column, target, deadlines: [{date, number}]}
403Can't edit the Project's targets
PATCH
/cohort_trackers/{id}/projects/{project_id}
Set a Cohort Tracker's targets on a Project
Requires authentication
Parameters
NameTypeDescription
target
query
integer One-off target: a number of Contacts to reach, not a total that adds up across periods
deadlines
query
array [{date: "YYYY-MM-DD", number}], replacing this tracker's deadline targets; [] clears them
Responses
200Targets saved
403Can't edit the Project's targets
422Bad deadlines, or neither field sent
GET
/cohort_trackers/{id}/albums/{bundle_id}
Get a Cohort Tracker's targets on an Album
Requires authentication
Parameters
NameTypeDescription
bundle_id
path
integer required Album ID
Responses
200{cohort_tracker_id, album_id, album_target_type, target, deadlines}
404The Album has no Project using the tracker
PATCH
/cohort_trackers/{id}/albums/{bundle_id}
Set a Cohort Tracker's targets on an Album
Requires authentication
Parameters
NameTypeDescription
target
query
integer One-off target for the Album; never the sum of its Projects'
deadlines
query
array [{date, number}], saved as the Album's manual targets
Responses
200Targets saved
403Can't edit the Album's targets
GET
/cohort_trackers/{id}/projects/{project_id}/results
Get a Cohort Tracker's result on a Project
Requires authentication
Parameters
NameTypeDescription
project_id
path
integer required Project ID
timeframe
query
string period, year_to_date or all_time (default). Each is worked out afresh: Year to Date is not the sum of the periods
as_of
query
date The deadline the window ends on (default: the next Target Deadline, or today)
page
query
integer Page of Contacts
per_page
query
integer Contacts per page (default 10, max 200)
Responses
200{count, eligible_count, target, starts_on, ends_on, page, page_size, page_count, total_count, data: [{id, name, qualifying_value}]}. A Contact you can't read is {restricted: true}
403Can't see the Project's Results Canvas
404The tracker isn't on the Project
422Unknown timeframe or bad date
GET
/cohort_trackers/{id}/albums/{bundle_id}/results
Get a Cohort Tracker's result on an Album
Requires authentication
Parameters
NameTypeDescription
bundle_id
path
integer required Album ID
timeframe
query
string period, year_to_date or all_time (default)
as_of
query
date The deadline the window ends on
page
query
integer Page of Contacts
per_page
query
integer Contacts per page (default 10, max 200)
Responses
200As for a Project. Each Contact counts once across the Album's Projects, so the result is never the sum of the Projects'
403Can't see the Album
404No Project in the Album uses the tracker
DELETE
/cohort_trackers/{id}/projects/{project_id}
Remove a Cohort Tracker from a Project
Requires authentication
Responses
204Removed
404Not on the Project
Impact framework

Filtered Metrics

A filtered version counts a standard metric again for only some responses and Contacts, e.g. "Session attendances — Female, under 21". The metric is a Change (Activity or Engagement tracker) or an Indicator (Choice, Achievement or Numerical tracker) already on the Project. It counts attendances or answers, not Contacts: to count Contacts, use a Cohort Tracker. It has its own row, name, column and targets on the Results Canvas, and Albums show every filtered version on their Projects.

response_criteria filters the responses, as a Progress Board's "Filter responses/stories by" does: story_category_ids (Surveys), wave_ids (Intervals), date_range (Date Happened, "dd/mm/yyyy - dd/mm/yyyy"), label_ids and author_ids. contact_criteria filters the Contacts tagged in them, in the Contact Filters format. Age is worked out at the date of each response; other Bio fields use the Contact's current value; the other sections are judged at the end of each reporting period.

✓ Workflow tip: Check the filters with POST /projects/{project_id}/filtered_metrics/preview, then add the filtered version with POST /projects/{project_id}/filtered_metrics. Read its figure with GET .../filtered_metrics/{id}/results.
GET
/projects/{project_id}/filtered_metrics
List a Project's filtered versions
Requires authentication
Parameters
NameTypeDescription
project_id
path
integer required Project ID
page
query
integer Page number
per_page
query
integer Records per page
last_synced_datetime
query
string ISO 8601 incremental sync
Responses
200Paginated list of filtered versions
403Can't see the Project's Results Canvas
POST
/projects/{project_id}/filtered_metrics/preview
Preview a filtered version
Requires authentication
Body: filtered_metric: {parent_type, parent_id, response_criteria, contact_criteria}.
Parameters
NameTypeDescription
project_id
path
integer required Project ID
Responses
200{count, total}: how many of the metric's tagged responses pass the filters, and how many there are
422The metric isn't on the Project, or a filter can't be applied
POST
/projects/{project_id}/filtered_metrics
Add a filtered version to a Project
Requires authentication
Body: filtered_metric: {parent_type: "Change"|"Indicator", parent_id, display_name, column, response_criteria, contact_criteria}. A Change's version goes after it in its column unless column is given; an Indicator's sits under its Outcome.
Parameters
NameTypeDescription
project_id
path
integer required Project ID
Responses
201Added
403Can't edit the Project's metrics
422The metric isn't on the Project, or validation failed
GET
/projects/{project_id}/filtered_metrics/{id}
Get a filtered version
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Filtered version ID
Responses
200The filtered version
404Not on the Project
PATCH
/projects/{project_id}/filtered_metrics/{id}
Update a filtered version
Requires authentication
Body: filtered_metric: {display_name, response_criteria, contact_criteria}. Criteria sent replace the stored ones.
Parameters
NameTypeDescription
id
path
integer required Filtered version ID
Responses
200Updated
403Can't edit the Project's metrics
422Validation failed
DELETE
/projects/{project_id}/filtered_metrics/{id}
Remove a filtered version from a Project
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Filtered version ID
Responses
204Removed; deleted once it is on no other Project or Scorecard Template
403Can't edit the Project's metrics
GET
/projects/{project_id}/filtered_metrics/{id}/results
Get a filtered version's result on a Project
Requires authentication
Parameters
NameTypeDescription
timeframe
query
string period, year_to_date or all_time (default)
as_of
query
string YYYY-MM-DD the timeframe ends; defaults to the next Target Deadline, or today
Responses
200{filtered_metric_id, timeframe, start_date, end_date, number, unit}
422Unknown timeframe or bad date
GET
/albums/{bundle_id}/filtered_metrics
List an Album's filtered versions
Requires authentication
Parameters
NameTypeDescription
bundle_id
path
integer required Album ID
Responses
200Paginated list: every filtered version on the Album's Projects
403Can't see the Album
GET
/albums/{bundle_id}/filtered_metrics/{id}
Get a filtered version on an Album
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Filtered version ID
Responses
200The filtered version
404Not on any of the Album's Projects
GET
/albums/{bundle_id}/filtered_metrics/{id}/results
Get a filtered version's result on an Album
Requires authentication
Parameters
NameTypeDescription
timeframe
query
string period, year_to_date or all_time (default)
as_of
query
string YYYY-MM-DD
Responses
200The result across the Album's open Projects
Events

Event Formats

Event Formats (Event Categories in the API) are the templates an organisation's events are created from, such as Workshops, Classes or Meetings. Only an Organisation Admin of the organisation that owns an Event Format can delete it, and only once it has no events and is not added to any project. Default formats can be deleted under the same rules.

DELETE
/event_categories/{id}
Delete an Event Format
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Event Format (Event Category) ID
Responses
200Deleted — returns id and message
403Not an Organisation Admin of the owning organisation
404Not found, or belongs to an organisation you are not in
422Has events or is added to projects — error gives the reason and counts
Reference data

Ratio Sets & Sub Ratios

Ratio Sets are reusable dropdown/list field definitions. Sub Ratios are the individual answer choices within a Ratio Set. Sub Ratio IDs are required when submitting Scale Indicator responses in a Story.

GET
/ratio_sets
List all Ratio Sets
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
Responses
200Paginated list — type: identity (Contact Bio Forms) or progress (Scale Indicators)
GET
/sub_ratios
List Sub Ratios (Answer Choices)
Requires authentication
Parameters
NameTypeDescription
ratio_set_ids[]
query
integer Filter by Ratio Set ID (repeat for multiple)
page
query
integer Page number
Responses
200Answer choices with priority, default_criteria, and default_points for verdict scoring
GET
/sub_ratios/{id}
Get a single Sub Ratio
Requires authentication
Parameters
NameTypeDescription
id
path
integer required Sub Ratio ID
Responses
200Sub Ratio record
404Not found
GET
/ratio_set_choiceables
List Ratio Set selection rules
Requires authentication
Parameters
NameTypeDescription
beneficiary_category_ids[]
query
integer Filter by Contact Bio Form ID
Responses
200Single/limited_multiple/unlimited_multiple choice rules per Ratio Set
Reference data

Case Forms

Case Forms (Custom Field Categories in the API) define the structured fields available on a Case. Each form contains Custom Field Definitions — the reusable fields — and Custom Field Category Definitions — the record created when a field is added to a form.

GET
/custom_field_categories
List all Case Forms
Requires authentication
Parameters
NameTypeDescription
page
query
integer Page number
per_page
query
integer Records per page
Responses
200Case Form schemas with field definition IDs and types