REST API

Read, create, and update people in your organisation programmatically. The API returns JSON and is authenticated with a personal access token you generate in the dashboard.

Authentication

Every request is scoped to a single organisation, resolved from the host you call, and authorised with a personal access token sent as a bearer token. The token carries exactly the permissions and division scope of the admin who created it.

  1. In the dashboard, open your account menu → API / MCP.
  2. Under Personal access tokens, give the token a name and click Generate token.
  3. Copy the token immediately — it's only shown once. Revoke it any time from the same page.

Send it in the Authorization header:

curl -H "Authorization: Bearer <token>" \
  https://your-subdomain.cobberhq.com.au/api/v1/people
Base URL: https://<your-subdomain>.cobberhq.com.au/api/v1 (or your custom domain). A token only works against the organisation it was created for. Requests without a valid token return 401 Unauthorized.

Conventions

  • Requests and responses are JSON. Send Content-Type: application/json on writes.
  • Success returns 200 (reads/updates) or 201 (create).
  • Validation failures return 422 with { "error": "validation_failed", "messages": [...] }.
  • A person you can't access returns 404 (never leaks existence).
  • List endpoints paginate with page and per_page (default 100, max 200).
  • In curl examples, always quote URLs that include ? query params. On macOS, zsh treats bare ? as a glob and fails with zsh: no matches found.
GET/api/v1/people

Search and list people you can access. Supports the same filters as the People page — e.g. search, tags, state, membership_status, volunteer_status, donor_status, branch, plus sort/direction.

curl -H "Authorization: Bearer <token>" \
  "https://your-subdomain.cobberhq.com.au/api/v1/people?search=smith&state=QLD&page=1"

Response

{
  "total_count": 128,
  "page": 1,
  "per_page": 100,
  "people": [
    {
      "id": 42,
      "url": "https://your-subdomain.cobberhq.com.au/dashboard/people/42",
      "name": "Jane Smith",
      "email": "jane@example.com",
      "mobile_phone": "+61 400 000 000",
      "suburb": "Brisbane",
      "state": "QLD",
      "tags": "member,volunteer",
      "membership_status": "Active",
      "volunteer_status": "active"
    }
  ]
}
GET/api/v1/people/:id

Full detail for one person, including address, electorates, tags, custom fields, email preferences, all email addresses, and recent activity.

curl -H "Authorization: Bearer <token>" \
  https://your-subdomain.cobberhq.com.au/api/v1/people/42

Response (abridged)

{
  "id": 42,
  "first_name": "Jane",
  "last_name": "Smith",
  "display_name": "Jane Smith",
  "residential_suburb": "Brisbane",
  "residential_state": "QLD",
  "tags": "member,volunteer",
  "custom_fields": { "party_membership": "Member" },
  "email_preferences": { "newsletters": true, "events": false },
  "volunteer_status": "active",
  "membership_status": "Active",
  "emails": [
    { "id": 55, "email": "jane@example.com", "primary": true, "unsubscribed": false, "bounced": false }
  ],
  "recent_actions": [
    { "type": "donation_made", "at": "2026-02-01T03:12:00Z", "details": { "amount": "50.0" } }
  ]
}
POST/api/v1/people

Create a person. Provide email to set their primary email address. You can set contact fields, tags, custom_fields, and email_preferences in the same call.

curl -X POST \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  https://your-subdomain.cobberhq.com.au/api/v1/people \
  -d '{
    "first_name": "Jane",
    "last_name": "Smith",
    "email": "jane@example.com",
    "tags": "member,volunteer",
    "custom_fields": { "party_membership": "Member" },
    "email_preferences": { "newsletters": true, "events": false }
  }'

Returns 201 with the created person in the same shape as Get a person.

PATCH/api/v1/people/:id

Update a person. Only the fields you include change. Notable fields:

  • email_preferences — an object of category => boolean for your organisation's email categories.
  • unsubscribe_all_emailstrue unsubscribes every email address on the record.
  • custom_fields — when provided, the keys you send are merged into the person's existing custom fields (other keys are kept). Omit it to leave custom fields untouched.
  • emails — array of { id?, email, primary?, remove? } to add/update/remove addresses.
curl -X PATCH \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  https://your-subdomain.cobberhq.com.au/api/v1/people/42 \
  -d '{
    "tags": "member,volunteer,lapsed",
    "email_preferences": { "newsletters": false },
    "unsubscribe_all_emails": true
  }'

Returns 200 with the updated person.

POST/api/v1/payments

Record a payment captured outside the online (Stripe) flow — a cash or cheque donation, EFTPOS at a stall, or a merchandise sale. It is stored as a succeeded payment and appears in the Finances report and on the person's profile, just like an online payment. Requires the finances.read permission.

Fields:

  • person_id — required; the person the payment is attributed to (must be one you can access).
  • amount — required; a positive decimal.
  • payment_methodcash, cheque, bank_transfer, or other.
  • payment_typedonation (default), other (e.g. merch), or event_ticket.
  • received_on — optional date the money was received (defaults to today); the payment is dated to this.
  • description, reason, tax_deductible — optional.
curl -X POST \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  https://your-subdomain.cobberhq.com.au/api/v1/payments \
  -d '{
    "person_id": 42,
    "amount": "50.00",
    "payment_method": "cash",
    "payment_type": "donation",
    "received_on": "2026-02-01",
    "description": "Cash donation at the branch stall"
  }'

Response

{
  "id": 918,
  "person_id": 42,
  "amount": "50.0",
  "payment_type": "donation",
  "payment_method": "cash",
  "status": "succeeded",
  "processed_at": "2026-02-01T00:00:00Z",
  "metadata": { "manual_entry": true, "created_by_admin": "you@example.com" }
}

MCP (AI assistants)

The same data is available to AI assistants over the Model Context Protocol. Point an MCP client (Claude, ChatGPT, etc.) at https://<your-subdomain>.cobberhq.com.au/mcp and it will walk you through signing in. See API / MCP in the dashboard for client-by-client setup.