Makerble API
The Makerble API gives you programmatic access to your CRM and impact measurement data — contacts, projects, surveys, cases, outcomes, and more.
| Property | Value |
|---|---|
| Base URL | https://makerble.com/api/v2 |
| Staging URL | https://staging.makerble.com/api/v2 |
| Mock URL | {{HOST}}/mock |
| Protocol | HTTPS · JSON · REST |
| Auth | Token-based headers — X-User-Email + X-User-Token |
| Spec | openapi.yaml · OpenAPI 3.0.3 |
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:
| Header | Value |
|---|---|
| X-User-Email | Your Makerble account email address |
| X-User-Token | Your authentication token from POST /users/sign_in |
Submit your email and password to receive your authentication token. Use this token in the X-User-Token header on all subsequent requests.
| Field | Type | Description | |
|---|---|---|---|
| user[email] | string | required | Your Makerble email address |
| user[password] | string | required | Your Makerble password |
user_id, email, and authentication_tokenPagination
All list endpoints support cursor-free offset pagination. The maximum per_page is 200.
| Parameter | Type | Default | Max | Description |
|---|---|---|---|---|
| page | integer | 1 | — | Page number |
| per_page | integer | 10 | 200 | Records per page |
| last_sync_datetime | string | — | — | ISO 8601 datetime — return only records updated after this value. Useful for incremental sync. |
{ page, page_size, page_count, total_count, data: [] }
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) |
|---|---|
| Organisation | Charity |
| Contact | Beneficiary |
| Contact Bio Form | Beneficiary Category |
| Survey | Story Category |
| Survey Campaign | Project Story Category |
| Survey Response / Timeline Update | Story |
| Activity / Engagement tracker | Change (stage: activity / participation) |
| Achievement / Choice / Numerical tracker | Indicator (type: binary / scale / value) |
| Dropdown / List field | Ratio Set |
| Answer Choice | Sub Ratio |
| Case Form | Custom Field Category |
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.
X-User-Email and X-User-Token to receive 200 responses rather than 401s.
curl {{HOST}}/mock/beneficiary_types -H "X-User-Email: test@example.com" -H "X-User-Token: mock-token"
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.
| Name | Type | Description | |
|---|---|---|---|
| id path |
integer | required | Organisation ID |
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).
| Name | Type | Description | |
|---|---|---|---|
| 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 |
| Name | Type | Description | |
|---|---|---|---|
| id path |
integer | required | Project ID |
role_data[].editor_ids, reporter_ids, or observer_ids.Users
Platform users with login credentials. Creating users requires a separate API Key — request one at api-key-request@makerble.com.
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page | |
| last_sync_datetime query |
string | ISO 8601 incremental sync |
| Name | Type | Description | |
|---|---|---|---|
| id path |
integer | required | User ID |
auth_code API Key. Password must be 8+ chars with at least one number, special character, and capital letter.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.
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.
| Name | Type | Description | |
|---|---|---|---|
| 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 |
| Name | Type | Description | |
|---|---|---|---|
| id path |
integer | required | Contact ID |
beneficiary.name, beneficiary.owner_id (User ID of the record owner). Submit custom field values as custom_fields: {"field_id": "value"}.| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page |
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page |
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.
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page |
| Name | Type | Description | |
|---|---|---|---|
| id path |
integer | required | Form ID |
| Name | Type | Description | |
|---|---|---|---|
| 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 |
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).
GET /custom_field_categories to discover field definition IDs before creating a Case.
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page | |
| last_sync_datetime query |
string | ISO 8601 incremental sync |
project_id, beneficiary_id. Submit case form values in custom_field_categories_definition: {field_definition_id: value}.| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page |
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number |
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.
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.
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page |
current_fields), the choice type (single/multiple) for each Scale Indicator (scale_indicator_choices), and scoring bands (verdict_data).| Name | Type | Description | |
|---|---|---|---|
| id path |
integer | required | Survey ID |
| Name | Type | Description | |
|---|---|---|---|
| id path |
integer | required | Survey ID |
| project_id query |
integer | required | Project the Survey Campaign belongs to |
| page query |
integer | Page number |
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page |
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.
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page | |
| last_sync_datetime query |
string | ISO 8601 incremental sync |
| Name | Type | Description | |
|---|---|---|---|
| id path |
integer | required | Story ID |
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.| Name | Type | Description | |
|---|---|---|---|
| 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 |
| Name | Type | Description | |
|---|---|---|---|
| id path |
integer | required | Story ID |
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.
| Name | Type | Description | |
|---|---|---|---|
| story_id query |
integer | Filter to a specific Story | |
| page query |
integer | Page number |
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number |
| Name | Type | Description | |
|---|---|---|---|
| story_id query |
integer | Filter to a specific Story | |
| page query |
integer | Page number |
| Name | Type | Description | |
|---|---|---|---|
| story_id query |
integer | Filter to a specific Story | |
| page query |
integer | Page number |
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number |
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.
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page | |
| last_sync_datetime query |
string | ISO 8601 incremental sync |
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).
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page |
| Name | Type | Description | |
|---|---|---|---|
| id path |
integer | required | Indicator ID |
| Name | Type | Description | |
|---|---|---|---|
| story_category_id query |
integer | Filter by Survey | |
| indicator_id query |
integer | Filter by Indicator |
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number |
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.
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page |
| Name | Type | Description | |
|---|---|---|---|
| id path |
integer | required | Outcome ID |
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.
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page |
| Name | Type | Description | |
|---|---|---|---|
| ratio_set_ids[] query |
integer | Filter by Ratio Set ID (repeat for multiple) | |
| page query |
integer | Page number |
| Name | Type | Description | |
|---|---|---|---|
| id path |
integer | required | Sub Ratio ID |
| Name | Type | Description | |
|---|---|---|---|
| beneficiary_category_ids[] query |
integer | Filter by Contact Bio Form ID |
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.
| Name | Type | Description | |
|---|---|---|---|
| page query |
integer | Page number | |
| per_page query |
integer | Records per page |