Forms

Read-only access to forms and their responses. List forms, page through a form's responses, fetch a single response with its full comment context, or pull everything that changed since a timestamp — built for external dashboards, BI tools, and historical analysis.

Required scopes: read:forms for the form endpoints, read:formresponses for the response endpoints.

Endpoints

GET
/api/open/v1/forms

List forms (published by default, paginated)

GET
/api/open/v1/forms/{id}

Get a single form

GET
/api/open/v1/forms/{id}/responses

List a form's responses (light payload, paginated)

GET
/api/open/v1/formresponses

Bulk feed of responses incl. form, comments and notes — ?since= for sync

GET
/api/open/v1/formresponses/{id}

Get a single response incl. form, comments and notes

List forms

curl "https://customer.monotree.com/api/open/v1/forms?status=published" \
  -H "Authorization: Bearer mono_your_token_here"
ParamNotes
statuspublished (default), draft, or all.
sinceOnly forms created at or after this timestamp — ISO 8601, e.g. 2026-05-20T08:00:00Z (see timestamp format).
per_pageDefault 25, max 50.

Form object

{
  "data": {
    "id": 12,
    "title": "Maintenance Request",
    "description": "Report broken equipment",
    "instructions": "Fill out all fields",
    "respondent_identity": "required",
    "is_anonymous": false,
    "is_commentable": true,
    "allow_multiple_responses": true,
    "is_published": true,
    "published_at": "2026-05-01T08:00:00+00:00",
    "groups": [
      { "id": 3, "name": "Kitchen Staff", "type": "department", "created_at": "2026-01-15T10:00:00+00:00" }
    ],
    "responses_count": 118,
    "created_at": "2026-04-28T09:00:00+00:00",
    "updated_at": "2026-05-01T08:00:00+00:00"
  }
}

respondent_identity is required, optional, or anonymous; is_anonymous is true when identity is always anonymous. groups is the form's targeting — empty for a company-wide form.

List a form's responses

A light payload — field responses without the comment threads. Use the single response or the bulk feed for full context.

curl "https://customer.monotree.com/api/open/v1/forms/12/responses?status=done" \
  -H "Authorization: Bearer mono_your_token_here"
ParamNotes
statusWorkflow status: todo, in_progress, done, or null (no status).
sinceOnly responses created at or after this timestamp — ISO 8601, e.g. 2026-05-20T08:00:00Z (see timestamp format).
per_pageDefault 25, max 100.
{
  "data": {
    "id": 4521,
    "form_id": 12,
    "form_title": "Maintenance Request",
    "is_anonymous": false,
    "status": "done",
    "respondent": { "id": 42, "name": "Jane Doe", "email": "jane@example.com" },
    "department": { "id": 3, "name": "Kitchen Staff", "type": "department" },
    "field_responses": [
      { "value": "Freezer 2 is above temperature", "field": { "id": 7, "title": "What happened?", "type": "text" } },
      { "value": [ { "id": 21, "title": "Urgent" } ], "field": { "id": 8, "title": "Priority", "type": "choices" } }
    ],
    "media": [
      { "id": 55, "type": "image", "mime_type": "image/jpeg", "filename": "freezer.jpg", "size": 182034, "url": "https://…/freezer.jpg", "width": 1280, "height": 960, "created_at": "2026-05-20T07:45:00+00:00" }
    ],
    "created_at": "2026-05-20T07:45:00+00:00",
    "updated_at": "2026-05-20T09:10:00+00:00"
  }
}

choices fields serialize their selections as { id, title } arrays; users and department_users fields as user objects. Hidden and archived responses are never returned.

Every response object (light and detail) includes media — the files uploaded with the submission. They belong to the response as a whole, not to a specific field. type is image, video or document, and url is a direct download link. On anonymous responses the files are stored encrypted, so url is a short-lived signed link (expires after ~5 minutes) — re-fetch the response whenever you need a fresh one.

Get a single response

Includes the embedded form, the shared public_comments thread, and the staff-only internal_comments — the full context for analysis.

curl https://customer.monotree.com/api/open/v1/formresponses/4521 \
  -H "Authorization: Bearer mono_your_token_here"
{
  "data": {
    "id": 4521,
    "form_id": 12,
    "...": "…same fields as the list payload…",
    "form": { "id": 12, "title": "Maintenance Request", "...": "…full form object…" },
    "public_comments": [
      {
        "id": 901,
        "body": "Could you re-check the freezer reading?",
        "form_response_id": 4521,
        "form_id": 12,
        "author": { "id": 5, "name": "Sam Owner", "email": "sam@example.com" },
        "media": [
          { "id": 77, "type": "image", "mime_type": "image/jpeg", "filename": "freezer.jpg", "url": "https://cdn.monotree.dk/…/freezer.jpg", "width": 1200, "height": 800 }
        ],
        "created_at": "2026-05-20T08:00:00+00:00",
        "updated_at": "2026-05-20T08:00:00+00:00"
      }
    ],
    "internal_comments": [
      {
        "id": 33,
        "body": "Escalated to facilities.",
        "form_response_id": 4521,
        "form_id": 12,
        "author": { "id": 5, "name": "Sam Owner", "email": "sam@example.com" },
        "created_at": "2026-05-20T08:05:00+00:00",
        "updated_at": "2026-05-20T08:05:00+00:00"
      }
    ]
  }
}
  • public_comments is the thread shared with the respondent; author is null when the comment was written by the respondent on an anonymous response. Attachments arrive in media.
  • internal_comments are staff-only notes — never visible to the respondent in the app, exposed here for complete context.

Bulk feed with since

GET /formresponses returns the same detail payload as the single fetch, paginated across all forms — no need to iterate form ids. Its since parameter filters on updated_at, so one poll captures everything that happened since your last sync: new responses, field or workflow-status edits, and new public or internal comments (each bumps the response's updated_at). Results are ordered by updated_at descending.

curl "https://customer.monotree.com/api/open/v1/formresponses?since=2026-05-20T00:00:00Z" \
  -H "Authorization: Bearer mono_your_token_here"
ParamNotes
sinceResponses created or updated at or after this timestamp — ISO 8601, e.g. 2026-05-20T08:00:00Z. Omit for a full dump (initial backfill).
statusWorkflow status: todo, in_progress, done, or null.
per_pageDefault 25, max 100.

An invalid since or status returns 422. For push-based integration, the outgoing webhooks fire on response creation, updates, and comment activity.

The since timestamp format

Every since parameter on these endpoints takes an ISO 8601 timestamp. Always include the timezone — Z for UTC or an explicit offset:

?since=2026-05-20T08:00:00Z            UTC
?since=2026-05-20T10:00:00%2B02:00     UTC+2 (a literal + must be url-encoded as %2B)
?since=2026-05-20                      date only — midnight in the platform's timezone

Values without a timezone are interpreted in the platform's timezone, so send an explicit Z/offset to avoid surprises. Anything that can't be parsed as a date returns 422. When syncing, use the updated_at of the newest record you've already processed (the API returns timestamps in ISO 8601 with offset), and remember the comparison is inclusive (>=) — records exactly on the boundary appear again.