Projects and forms
Projects group forms; forms hold the questions and produce submissions. Every call needs a Bearer token.
Authentication explains how to obtain the Bearer token used by every call below.
Projects
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /projects | Create a project in a workspace (workspaceId, name; country and region defaults are optional). |
| GET | /projects | List the projects you can access. |
| GET | /projects/{id} | Read one project. |
| PATCH | /projects/{id} | Update the project — name, description, visibility, timezone, active regions. |
| POST | /projects/{id}/activate | Move a draft project to active. |
| POST | /projects/{id}/archive | Archive a project. |
| POST | /projects/{id}/restore-draft | Return an archived project to draft. |
| DELETE | /projects/{id} | Delete a project. |
| PUT | /projects/{id}/logo | Attach a logo to the project (logoFileId from a file upload). |
| DELETE | /projects/{id}/logo | Remove the project logo. |
curl -X POST https://<votre-serveur>/api/projects \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"workspaceId":"<workspace-id>","name":"Household survey 2026"}'
Project members and regions
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /projects/{id}/memberships | List the project's members. |
| POST | /projects/{id}/memberships | Add a member or update one: userId, role, optional assignedCountries, assignedRegions and reportsToUserId. |
| PATCH | /projects/{id}/memberships/{user_id}/role | Change a member's role. |
| PUT | /projects/{id}/memberships/{user_id}/regions | Replace a member's regional assignment and reports-to link. The role is not touched; null clears the assignment. |
| DELETE | /projects/{id}/memberships/{user_id} | Remove a member from the project. |
Roles are admin, manager, analyst, surveyor, validator and guest.
curl -X PUT https://<votre-serveur>/api/projects/<project-id>/memberships/<user-id>/regions \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"assignedRegions":["NDJ","BHR"]}'
Forms
| Method | Endpoint | Purpose |
|---|---|---|
| POST | /forms | Create a form inside a project (projectId, title, schemaXml). |
| GET | /forms | List forms, filterable by project and status. |
| GET | /forms/{id} | Read a form with its schema. |
| PATCH | /forms/{id} | Update the form. |
| PATCH | /forms/{id}/metadata | Update metadata only. |
| PATCH | /forms/{id}/project | Move the form to another project. |
| POST | /forms/{id}/clone | Clone the form. |
| POST | /forms/{id}/archive | Archive the form. |
| POST | /forms/{id}/restore-draft | Bring an archived form back to draft. |
| DELETE | /forms/{id} | Delete the form. A form that already has submissions can only be deleted by a project manager. |
| GET | /forms/{id}/stats | Collection statistics for the form. |
| GET | /forms/{id}/export | Export the form as a readable HTML document built from its latest version. |
| POST | /forms/{id}/uploads | Upload a file used by the form (base64 payload, 25 MB maximum per file). |
Draft, approval and versions
A form starts as a draft. The builder's working state is saved to the draft endpoints without creating a version. Submitting for approval moves the form to pending approval; an administrator approves it (publishing it) or rejects it, which returns it to draft with a reason.
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /forms/{id}/draft | Read the saved builder draft. |
| PUT | /forms/{id}/draft | Save the builder draft without appending a version. |
| POST | /forms/{id}/submit-for-approval | Submit a draft form for approval. It needs a saved version with labelled questions. |
| POST | /forms/{id}/approve | Approve a pending form (administrator) and make the approved version live. |
| POST | /forms/{id}/reject-approval | Reject a pending form with a reason (administrator); the form returns to draft. |
| POST | /forms/{id}/versions | Save a new version of the form. |
| GET | /forms/{id}/versions | List the versions of a form. |
| GET | /forms/versions/{id} | Read one version directly. |
| GET | /forms/{form_id}/versions/{v1_id}/diff | Compare two versions: pass the version to compare against as vs. |
curl "https://<votre-serveur>/api/forms/<form-id>/versions/<v1-id>/diff?vs=<v2-id>" \
-H "Authorization: Bearer $TOKEN"
Deployments
Each version gets a deployment. A deployment is live, test or disabled; only a live deployment accepts submissions, and approving a form makes the approved version live.
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /forms/{id}/deployments | List the deployments of a form. |
| POST | /forms/{id}/deployments/{deployment_id}/test | Mark a version for test collection. |
| POST | /forms/{id}/deployments/{deployment_id}/live | Make a version live. |
| POST | /forms/{id}/deployments/{deployment_id}/disable | Disable a deployment. |
Form settings
GET /forms/{id}/settings returns the form's collection settings, with defaults applied when nothing was ever set; PATCH updates a subset of the keys.
| Setting | Effect |
|---|---|
| collectScope | any (default) lets any authenticated account submit; surveyor restricts submissions to accounts holding the surveyor role in the form's workspace. |
| regionScope | project, countries or custom. With custom, the form is visible only to members whose assigned regions intersect targetRegions. |
The settings object also carries the form's collection preferences: allowEdits, allowDelete, requireGeo, dedupKey, dailyQuota, windowStartsAt, windowEndsAt, captureDeviceId, captureUsername, capturePhone, captureEmail, validationRequired, autoRejectOnHigh, targetCountries and targetRegions.
Public collection link
A form can be shared as an anonymous link. The form must be published with a live deployment, and the workspace's anonymousCollect master switch must be enabled; otherwise the request is refused. By default the submission window runs from now until 30 days later, and endsAt must be after startsAt.
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /forms/{id}/public-link | Read the link state: enabled, url (/collect/{token}), startsAt, endsAt. |
| POST | /forms/{id}/public-link | Generate or regenerate the link. Optional startsAt and endsAt set the submission window. |
| DELETE | /forms/{id}/public-link | Disable the link immediately. |
Submissions sent through the link are accepted only when the form also allows anonymous submissions.
curl -X POST https://<votre-serveur>/api/forms/<form-id>/public-link \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"endsAt":"2027-01-31T23:59:59Z"}'
Validation criteria
A form can carry field-level validation criteria, evaluated by the validation engine on each run. A criterion targets a question, an operator (required, eq, neq, gt, gte, lt, lte, between, in, regex, unique), a severity (low, medium, high), an action (flag, auto_reject, require_correction) and an optional region scope.
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /forms/{id}/criteria | List the form's criteria. |
| POST | /forms/{id}/criteria | Create a criterion (questionName, operator, value, severity, action). |
| PATCH | /forms/{id}/criteria/{criteria_id} | Update a criterion. |
| DELETE | /forms/{id}/criteria/{criteria_id} | Delete a criterion. |
Question library and templates
| Method | Endpoint | Purpose |
|---|---|---|
| GET | /forms/question-library | List the workspace's saved questions. |
| POST | /forms/question-library | Save a question to the library. |
| DELETE | /forms/question-library/{id} | Remove a question from the library. |
| GET | /forms/templates | List the available form templates. |
| POST | /forms/templates/{id}/use | Create a new form from a template. |
Related pages
- Create a project — the same steps through the interface.
- Create your first form — design, publish and share a form.
- Submissions — what these forms collect.
- Errors and limits — status codes, error format and size limits.