Forms
Create, configure, and archive forms programmatically; manage questions with conditional logic; submit and transition responses through the workflow state machine.
On this page
List forms
Returns every form in the caller's organization (archived excluded by default). Supports filtering by scope, owner, searching by name, sorting by name/date/total responses, date ranges, and optional question inclusion. Capabilities — editing, response visibility, state changes — are governed by the form's permissions; owner and org admins always have full access.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| search | string | Optional | Case-insensitive search on form name. Matches system forms and user-created forms. Max 200 chars. |
| filter | string | Optional | Scope filter. One of: all, public, approval, workflow, archived. Default: all org forms. Deprecated value: me — use owner_user_ids with your own UUID instead. |
| owner_user_ids | string (CSV) | Optional | Filter by form owner UUIDs. Comma-separated (max 50), OR semantics. ANDs with every other param (search, filter, pagination, ordering). Cross-org UUIDs never match. Replaces the deprecated filter=me. |
| order | string | Optional | Sort field. One of: alphabetical, recent, total. Default: recent. |
| is_ascend | boolean | Optional | Sort direction. true for ascending, false for descending. Default: false. |
| include | string | Optional | Comma-separated list of extra fields to include. Currently supports: questions (returns each form's questions with UUID, label, type, options). |
| include_archived | boolean | Optional | When true, includes archived forms in results. Not needed when using filter=archived. Default: false. |
| start_date | string (YYYY-MM-DD) | Optional | Filter forms created on or after this date. Inclusive, caller's timezone. |
| end_date | string (YYYY-MM-DD) | Optional | Filter forms created on or before this date. Inclusive, caller's timezone. |
| offset | integer | Optional | Pagination offset. Default: 0. |
| limit | integer | Optional | Page size. Default: 25, max: 50. |
Response
{
"count": "integer",
"next": "string | null",
"previous": "string | null",
"results": "array<{ uuid, name, is_active, collect_responses_anonymously, privacy, shortcut, start_on, end_on, is_archived, workflow_enabled, approval_flow_enabled, created_at, questions? }>"
}Errors
| Status | When |
|---|---|
| 400 | Validation error (invalid_filter, invalid_order, search_query_too_long, invalid_date_range, invalid_owner_user_id, too_many_owner_user_ids) |
| 401 | Missing/invalid/expired credential |
| 403 | Authenticated but not permitted |
| 429 | Throttled — Retry-After header set |
curl -sS 'https://api.dailybot.com/v1/forms/?filter=workflow&order=alphabetical&is_ascend=true' \
-H 'X-API-KEY: $DAILYBOT_API_KEY'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- When include=questions is set, each form object includes a questions array with UUID, label, type, required flag, and options for each question.
- Deprecated: filter=me — use owner_user_ids with your own user UUID instead. Legacy clients keep working: me still resolves to the caller's owner scope and intersects with any explicit owner_user_ids. The me scoping on form responses endpoints is unrelated and NOT deprecated. Both filter=me and available_on_list_view remain accepted indefinitely; removal will be announced as a separate changelog entry with its own migration window.
- Deprecated: available_on_list_view — still accepted on POST /v1/forms/create/ and PATCH /v1/forms/{uuid}/config/ but ignored server-side. List visibility is now org-wide. To hide a form from the list, archive it instead.
Create a form with inline questions
Creates a new form with at least one question and optional configuration (workflow, permissions, approval, ChatOps command, report channels). Requires admin or manager role.
Request body
{
"name": "string (required, min 3)",
"questions": "array (required, min 1)",
"report_channels": "string[] (max 3)",
"generate_short_question": "boolean (optional, top-level)"
}Response
{
"uuid": "string (uuid)",
"name": "string",
"questions": "array",
"report_channels": "array",
"public_url": "string|null"
}Errors
| Status | When |
|---|---|
| 401 | Missing or invalid credential |
| 403 | Insufficient permissions (admin/manager required for write) |
| 429 | Rate limited — Retry-After header set |
| 400 | questions_required, unknown_field, report_channel_not_found, too_many_report_channels |
curl -sS -X POST 'https://api.dailybot.com/v1/forms/create/' -H 'X-API-KEY: $DAILYBOT_API_KEY' -H 'Content-Type: application/json' -d '{"name":"Incident Report","questions":[{"type":"text","label":"What happened?","short_question":"Description"}]}'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Field aliases: question_type for type, question for label. short_question required on each question unless generate_short_question: true at request level.
List form owners
Paginated, searchable picker of org members who own at least one non-archived form. Only active, approved members appear. Ordered by full_name ascending. Designed for UI pickers: a 1000-member org returns only its (typically few) form owners, not the whole member directory.
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| search | string | Optional | Case-insensitive search on member name and email. Email is matched server-side for all callers but the email value is only returned to callers with email visibility (admins, managers, team admins). |
| offset | integer | Optional | Pagination offset. Default: 0. |
| limit | integer | Optional | Page size. Default: 20, max: 50. |
Response
{
"count": "integer",
"next": "string | null",
"previous": "string | null",
"results": "array<{ uuid, full_name, image, role, email (conditional — present only for admin/manager/team-admin-scoped callers) }>"
}Errors
| Status | When |
|---|---|
| 400 | Validation error (search_query_too_long) |
| 401 | Missing/invalid/expired credential |
| 403 | Authenticated but not permitted |
| 429 | Throttled — Retry-After header set |
curl -sS 'https://api.dailybot.com/v1/forms/form-owners/?search=serg&limit=20' \
-H 'X-API-KEY: $DAILYBOT_API_KEY'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- Member emails are hidden in picker payloads. The email field appears ONLY when the caller has email visibility — org admins, managers, and team admins. Member-scoped callers receive rows without the email key (omitted entirely, never null). API keys inherit the key owner's role. search still matches on email server-side for every caller, but the value is never echoed back to callers without visibility.
- The role field contains the org role slug: ADMIN_ORG, MANAGER, ADMIN, MEMBER, or GUEST.
Retrieve a form
Retrieve a form by UUID. The read gate is org membership — any authenticated member of the organization can read any form. The privacy and available_on_list_view fields do not affect who can read the form; capabilities like editing, seeing responses, and changing workflow states are governed by the form's per-scope permissions (owner and org admins always have full access).
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string (uuid) | Required | — |
Response
{
"uuid": "string (uuid)",
"name": "string",
"is_active": "boolean",
"collect_responses_anonymously": "boolean",
"privacy": "string",
"questions": "array",
"workflow": "object",
"created_at": "string (ISO 8601)"
}Errors
| Status | When |
|---|---|
| 401 | Missing/invalid/expired credential |
| 403 | Authenticated but not permitted |
| 429 | Throttled — Retry-After header set |
| 404 | Form not found or caller is not an org member |
curl -sS -X GET 'https://api.dailybot.com/v1/forms/{uuid}/' -H 'X-API-KEY: $DAILYBOT_API_KEY'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- The detail read gate is org membership. The privacy field reflects the form's submission scope (OWNER, TEAM, EVERYONE), not who can read the form definition. The available_on_list_view field is deprecated and has no effect — all org forms now appear in the list endpoint.
Update form configuration
Partial update of form metadata and configuration. Unknown fields return 400 unknown_field. approvers and permission audiences use full-replace semantics.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string (uuid) | Required | — |
Request body
{
"name": "string?",
"workflow": "object?",
"who_can_edit": "object?",
"report_channels": "string[]?"
}Response
{
"id": "uuid",
"name": "string",
"questions": "array",
"workflow": "object"
}Errors
| Status | When |
|---|---|
| 401 | Missing or invalid credential |
| 403 | Insufficient permissions (admin/manager required for write) |
| 429 | Rate limited — Retry-After header set |
| 400 | unknown_field, workflow_requires_states, invalid_permission_audience, command_already_exists |
| 404 | form_not_found |
curl -sS -X PATCH 'https://api.dailybot.com/v1/forms/{uuid}/config/' -H 'X-API-KEY: $DAILYBOT_API_KEY' -H 'Content-Type: application/json' -d '{"allow_public_responses":true}'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- report_channels array fully replaces the current set (max 3). Channel IDs must exist in GET /v1/report-channels/.
Archive (deactivate) a form
Sets the form inactive and archived. Idempotent — re-archiving returns 204.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string (uuid) | Required | — |
Errors
| Status | When |
|---|---|
| 401 | Missing or invalid credential |
| 403 | Insufficient permissions (admin/manager required for write) |
| 429 | Rate limited — Retry-After header set |
| 404 | form_not_found |
curl -sS -X DELETE 'https://api.dailybot.com/v1/forms/{uuid}/archive/' -H 'X-API-KEY: $DAILYBOT_API_KEY'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
Add a question to a form
Add a question to a form. Question types: text, boolean, multiple_choice, numeric. Max 50 questions per form.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string (uuid) | Required | — |
Request body
{
"type": "string",
"label": "string",
"short_question": "string (required unless generate_short_question)"
}Errors
| Status | When |
|---|---|
| 401 | Missing or invalid credential |
| 403 | Insufficient permissions (admin/manager required for write) |
| 429 | Rate limited — Retry-After header set |
| 400 | short_question_required, invalid_question_type, question_uuids_incomplete |
curl -sS -X POST 'https://api.dailybot.com/v1/forms/{uuid}/questions/' -H 'X-API-KEY: $DAILYBOT_API_KEY' -H 'Content-Type: application/json'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
Update a form question
Update a form question. Question types: text, boolean, multiple_choice, numeric. Max 50 questions per form.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string (uuid) | Required | — |
| q_uuid | string (uuid) | Required | — |
Request body
{
"type": "string",
"label": "string",
"short_question": "string (required unless generate_short_question)"
}Errors
| Status | When |
|---|---|
| 401 | Missing or invalid credential |
| 403 | Insufficient permissions (admin/manager required for write) |
| 429 | Rate limited — Retry-After header set |
| 400 | short_question_required, invalid_question_type, question_uuids_incomplete |
curl -sS -X PATCH 'https://api.dailybot.com/v1/forms/{uuid}/questions/{q_uuid}/' -H 'X-API-KEY: $DAILYBOT_API_KEY' -H 'Content-Type: application/json'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
Delete a form question
Delete a form question. Question types: text, boolean, multiple_choice, numeric. Max 50 questions per form.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string (uuid) | Required | — |
| q_uuid | string (uuid) | Required | — |
Request body
{
"type": "string",
"label": "string",
"short_question": "string (required unless generate_short_question)"
}Errors
| Status | When |
|---|---|
| 401 | Missing or invalid credential |
| 403 | Insufficient permissions (admin/manager required for write) |
| 429 | Rate limited — Retry-After header set |
| 400 | short_question_required, invalid_question_type, question_uuids_incomplete |
curl -sS -X DELETE 'https://api.dailybot.com/v1/forms/{uuid}/questions/{q_uuid}/delete/' -H 'X-API-KEY: $DAILYBOT_API_KEY' -H 'Content-Type: application/json'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
Reorder all form questions
Reorder all form questions. Question types: text, boolean, multiple_choice, numeric. Max 50 questions per form.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string (uuid) | Required | — |
Request body
{
"question_uuids": "uuid[] (required, complete set)"
}Errors
| Status | When |
|---|---|
| 401 | Missing or invalid credential |
| 403 | Insufficient permissions (admin/manager required for write) |
| 429 | Rate limited — Retry-After header set |
| 400 | short_question_required, invalid_question_type, question_uuids_incomplete |
curl -sS -X PUT 'https://api.dailybot.com/v1/forms/{uuid}/questions/reorder/' -H 'X-API-KEY: $DAILYBOT_API_KEY' -H 'Content-Type: application/json'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- question_uuids must include every question UUID exactly once.
List form responses
Paginated list of form responses. By default returns only the caller's own responses. With all=true or any advanced filter (submission_sources, submitter_user_ids, flow_status), returns all responses and requires VIEW_REPORTS permission. Supports full-text search, submission source filtering, workflow state filtering, approval flow status, date ranges, and sorting.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string (uuid) | Required | — |
Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
| all | boolean | Optional | Return all responses. Requires VIEW_REPORTS permission on the form. Default: false (own responses only). |
| user | string (uuid) | Optional | Filter by specific submitter UUID. Requires VIEW_REPORTS permission. Invalid UUIDs return 400 invalid_user_identifier. |
| search | string | Optional | Full-text search across response content, submitter name, and submitter email. Anonymous member identities are not searchable (privacy). Max 256 chars. |
| submission_sources | string (CSV) | Optional | Filter by submission origin. Comma-separated, OR semantics. Values: member, anonymous, automation, public. Requires VIEW_REPORTS permission. |
| submitter_user_ids | string (CSV) | Optional | Filter by submitter UUIDs. Comma-separated (max 50), OR semantics. Requires VIEW_REPORTS permission. |
| flow_status | string | Optional | Approval flow status. One of: pending, approved, denied. Silently ignored if the form has no approval flow. Requires VIEW_REPORTS permission. |
| state | string | Optional | Workflow state key (e.g. draft, in_review, done). Returns 400 invalid_workflow_state if the form has no workflow. |
| order | string | Optional | Sort direction. One of: recent (newest first), oldest. Default: recent. |
| is_ascend | boolean | Optional | When true, equivalent to order=oldest. Default: false. |
| start_date | string (YYYY-MM-DD) | Optional | Filter by creation date range start. Inclusive, caller's timezone. |
| end_date | string (YYYY-MM-DD) | Optional | Filter by creation date range end. Inclusive, caller's timezone. |
| offset | integer | Optional | Pagination offset. Default: 0. |
| limit | integer | Optional | Page size. Default: 25, max: 50. |
Response
{
"count": "integer",
"next": "string | null",
"previous": "string | null",
"results": "array<{ uuid, user, is_dailybot_bot, is_guest_user, is_anonymous, guest_user, submission_source, flow_status, current_state, content, response_completed, has_issue, created_at, updated_at }>"
}Errors
| Status | When |
|---|---|
| 400 | Validation error (invalid_submission_sources, invalid_submitter_user_id, too_many_submitter_user_ids, invalid_flow_status, invalid_workflow_state, invalid_user_identifier, search_query_too_long, invalid_date_range) |
| 401 | Missing/invalid/expired credential |
| 403 | Caller lacks VIEW_REPORTS permission for advanced filters (form_response_view_all_forbidden) |
| 429 | Throttled — Retry-After header set |
curl -sS 'https://api.dailybot.com/v1/forms/{uuid}/responses/?all=true&submission_sources=automation,public&order=recent' \
-H 'X-API-KEY: $DAILYBOT_API_KEY'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- All filters compose with AND across groups and OR within each group. Example: submission_sources=member,automation AND flow_status=pending returns member OR automation responses that are pending approval.
- Using any advanced filter (submission_sources, submitter_user_ids, flow_status) automatically implies all=true and requires VIEW_REPORTS permission.
Create a form response
Submit a new response to a form. The content field maps each question UUID to its answer value. Optionally use automation mode (no submitter attribution), anonymous mode (random generated name), guest identity (external person metadata), or a submission source label for traceability.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string (uuid) | Required | — |
Request body
{
"content": "object (required) — answers keyed by question UUID. Values can be strings, booleans, numbers, or arrays of scalars for multiple-choice.",
"automation": "boolean (optional, default: false) — submit as automation; channel notifications show no submitter. Response marked with is_dailybot_bot=true.",
"anonymous": "boolean (optional, default: false) — submit anonymously; channel notifications show a random generated name.",
"guest_user": "object (optional) — guest identity for the submission: { full_name: string (max 255), email: string (max 254) }. Only accepted when automation=true; silently ignored otherwise. Required when form has email_and_name_mandatory enabled.",
"submission_source": "string (optional, max 512) — free-text provenance label stored in response metadata (e.g. \"github-actions:deploy-pipeline\", \"zapier:feedback-sync\")"
}Response
{
"uuid": "string (uuid)",
"form": "string (uuid)",
"content": "object — question UUID → answer value",
"response_completed": "boolean",
"has_issue": "boolean",
"blockers_status": "string | null",
"is_anonymous": "boolean",
"is_dailybot_bot": "boolean — true when submitted as automation",
"is_guest_user": "boolean — true when guest identity was recorded",
"guest_user": "object | null — { full_name, email } when guest identity exists",
"submission_source": "string | null — provenance label from metadata",
"created_at": "string (ISO 8601)"
}Errors
| Status | When |
|---|---|
| 400 | Validation error (missing content, invalid question UUIDs, required questions not answered, guest_user_required when form mandates name+email, invalid email format, submission_source exceeds 512 chars) |
| 401 | Missing/invalid/expired credential |
| 403 | Authenticated but not permitted |
| 404 | Form not found or not visible |
| 413 | Request body exceeds 64 KB limit |
| 429 | Throttled — Retry-After header set |
curl -s -X POST \
-H 'X-API-KEY: $DAILYBOT_API_KEY' \
-H 'Content-Type: application/json' \
'https://api.dailybot.com/v1/forms/{uuid}/responses/' \
-d '{
"content": {"<question-uuid>": "Approved"},
"automation": true,
"guest_user": {"full_name": "Ops Bot", "email": "ops@company.com"},
"submission_source": "workflow:on-call-handoff"
}'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
- When automation is true, the response appears without user attribution in channel notifications — ideal for CI/CD pipelines, web form bridges, or webhook forwarding. The is_dailybot_bot field in the response confirms automation mode.
- When anonymous is true, a random generated name (e.g., "Purple Elephant") replaces the real submitter in channel notifications. If both automation and anonymous are true, automation takes precedence.
- Use guest_user to attach external identity (name + email) to automation submissions. Required when the form has email_and_name_mandatory enabled. Use submission_source to tag which integration or workflow produced the response.
Retrieve a form response
Retrieve a single form response identified by uuid. Returns current_state, allowed_transitions, and content.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string (uuid) | Required | — |
| response_uuid | string (uuid) | Required | — |
Response
{
"uuid": "string (uuid)",
"form": "string (uuid)",
"content": "array",
"current_state": "string",
"allowed_transitions": "array<string>",
"response_completed": "boolean",
"has_issue": "boolean",
"blockers_status": "string | null",
"is_anonymous": "boolean",
"is_dailybot_bot": "boolean",
"is_guest_user": "boolean",
"guest_user": "object | null — { full_name, email }",
"submission_source": "string | null",
"flow_status": "string | null — approval status: approved, denied, or null (pending/no flow)",
"created_at": "string (ISO 8601)",
"updated_at": "string (ISO 8601)"
}Errors
| Status | When |
|---|---|
| 401 | Missing/invalid/expired credential |
| 403 | Authenticated but not permitted |
| 429 | Throttled - Retry-After header set |
| 404 | Not found or not visible |
curl -sS -X GET 'https://api.dailybot.com/v1/forms/{uuid}/responses/{response_uuid}/' -H 'X-API-KEY: $DAILYBOT_API_KEY'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
Update a form response
Update a form response identified by uuid. Response returns the updated resource including current_state and allowed_transitions.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string (uuid) | Required | — |
| response_uuid | string (uuid) | Required | — |
Request body
{
"content": "array (optional)",
"response_completed": "boolean (optional)"
}Response
{
"uuid": "string (uuid)",
"form": "string (uuid)",
"content": "array",
"current_state": "string",
"allowed_transitions": "array<string>",
"response_completed": "boolean",
"updated_at": "string (ISO 8601)"
}Errors
| Status | When |
|---|---|
| 401 | Missing/invalid/expired credential |
| 403 | Authenticated but not permitted |
| 429 | Throttled - Retry-After header set |
| 400 | Validation error |
| 404 | Not found or not visible |
curl -sS -X PATCH 'https://api.dailybot.com/v1/forms/{uuid}/responses/{response_uuid}/' -H 'X-API-KEY: $DAILYBOT_API_KEY'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
Delete a form response
Delete a form response
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string (uuid) | Required | — |
| response_uuid | string (uuid) | Required | — |
Errors
| Status | When |
|---|---|
| 401 | Missing/invalid/expired credential |
| 403 | Authenticated but not permitted |
| 429 | Throttled - Retry-After header set |
| 404 | Not found or not visible |
curl -sS -X DELETE 'https://api.dailybot.com/v1/forms/{uuid}/responses/{response_uuid}/' -H 'X-API-KEY: $DAILYBOT_API_KEY'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
Transition a form response state
Runs the state machine transition. Body: to_state, optional note.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| uuid | string (uuid) | Required | — |
| response_uuid | string (uuid) | Required | — |
Request body
{
"to_state": "string (required)",
"note": "string (optional)"
}Response
{
"uuid": "string (uuid)",
"form": "string (uuid)",
"current_state": "string",
"allowed_transitions": "array<string>",
"content": "array",
"updated_at": "string (ISO 8601)"
}Errors
| Status | When |
|---|---|
| 401 | Missing/invalid/expired credential |
| 403 | Authenticated but not permitted |
| 429 | Throttled - Retry-After header set |
| 400 | Validation error |
| 404 | Not found or not visible |
| 409 | State-machine conflict |
curl -sS -X POST 'https://api.dailybot.com/v1/forms/{uuid}/responses/{response_uuid}/transition/' -H 'X-API-KEY: $DAILYBOT_API_KEY'Try it
This is a copy-only helper — the request is not sent from your browser. Paste the command into your terminal to execute it.
Forms
Programmatic access to Dailybot forms — list, filter, sort, search, submit responses with automation or anonymous modes, attach guest identities, transition through workflow states, and manage approval flows.
See the full endpoint reference — with parameters, request/response schemas, error codes, and code samples — at the interactive page: /developers/api/forms.
Every endpoint in this group accepts either an API key (X-API-KEY) or a CLI Bearer token (Authorization: Bearer …) unless explicitly marked otherwise, per the auth method matrix at /developers/authentication#parity-matrix.
Identifier
The Form and Form Response resources use a dedicated uuid field (RFC 4122 v4) as the canonical identifier in every request and response. Path parameters like /v1/forms/{uuid}/responses/{response_uuid}/ also use the uuid value.
Pagination
All list endpoints return the standard pagination envelope:
{
"count": 42,
"next": "https://api.dailybot.com/v1/forms/?offset=25&limit=25",
"previous": null,
"results": [...]
}
| Parameter | Type | Default | Max | Description |
|---|---|---|---|---|
offset |
integer | 0 | — | Pagination offset |
limit |
integer | 25 | 50 | Page size |
See /developers/conventions#pagination for the full spec.
Listing forms
GET /v1/forms/ returns every form in the caller’s organization (archived excluded by default). Capabilities — editing, response visibility, state changes — are governed by the form’s permissions; owner and org admins always have full access.
Supports filtering by scope, owner, searching by name, sorting, and date ranges.
Scope filters (?filter=):
| Value | Description |
|---|---|
all |
All org forms (default) |
public |
Only forms with privacy = EVERYONE |
approval |
Only forms with approval flow enabled |
workflow |
Only forms with workflow states enabled |
archived |
Only archived forms |
me |
Deprecated — use owner_user_ids with your own UUID instead. Still works for backward compatibility. |
Owner filter (?owner_user_ids=): Comma-separated user UUIDs (max 50). Returns only forms owned by those users. ANDs with every other parameter (search, filter, pagination, ordering). Cross-org UUIDs never match (returns 0 rows, not an error). Replaces the deprecated filter=me.
Sorting (?order=):
| Value | Description |
|---|---|
recent |
By creation date, newest first (default) |
alphabetical |
By form name |
total |
By total number of responses |
Use ?is_ascend=true to reverse the sort direction.
# Workflow forms, sorted alphabetically ascending
curl -H "X-API-KEY: $DAILYBOT_API_KEY" \
"https://api.dailybot.com/v1/forms/?filter=workflow&order=alphabetical&is_ascend=true"
# Search by name
curl -H "X-API-KEY: $DAILYBOT_API_KEY" \
"https://api.dailybot.com/v1/forms/?search=Access%20Request"
# Forms sorted by most responses
curl -H "X-API-KEY: $DAILYBOT_API_KEY" \
"https://api.dailybot.com/v1/forms/?order=total"
Including questions — pass ?include=questions to embed each form’s questions inline:
{
"uuid": "...",
"name": "Sprint Review",
"questions": [
{
"uuid": "q-uuid-1",
"label": "What did you accomplish?",
"type": "text",
"required": true,
"options": null
}
]
}
Discovering form owners
GET /v1/forms/form-owners/ returns a paginated, searchable list of org members who own at least one non-archived form. Only active, approved members appear. Ordered by full_name ascending.
Designed for UI pickers: a 1000-member org returns only its (typically few) form owners, not the whole member directory.
| Parameter | Type | Default | Max | Description |
|---|---|---|---|---|
search |
string | — | — | Case-insensitive search on name and email |
offset |
integer | 0 | — | Pagination offset |
limit |
integer | 20 | 50 | Page size |
Each result contains uuid, full_name, image, and role (org role slug: ADMIN_ORG, MANAGER, ADMIN, MEMBER, GUEST).
Email visibility: the email field appears only when the caller has email visibility — org admins, managers, and team admins. Member-scoped callers receive rows without the email key (omitted entirely, never null). API keys inherit the key owner’s role. The search parameter still matches on email server-side for every caller, but the value is never echoed back to callers without visibility. Integrators must not assume email is present on picker rows.
# Search form owners by name
curl -H "X-API-KEY: $DAILYBOT_API_KEY" \
"https://api.dailybot.com/v1/forms/form-owners/?search=serg&limit=20"
# Filter forms list by owner
curl -H "X-API-KEY: $DAILYBOT_API_KEY" \
"https://api.dailybot.com/v1/forms/?owner_user_ids=<uuid-1>,<uuid-2>"
Deprecated fields:
available_on_list_view— still accepted onPOST /v1/forms/create/andPATCH /v1/forms/{uuid}/config/but is a server-side no-op. List visibility is now org-wide. To hide a form, archive it.filter=me— still works for backward compatibility but is deprecated. Useowner_user_idswith your own user UUID instead. When both are sent, they intersect. Themescoping on form responses endpoints is unrelated and not deprecated.
Both deprecated fields remain accepted indefinitely; removal (and the eventual column drop) will be announced as a separate changelog entry with its own migration window. Integrators should migrate now but nothing breaks on deploy day.
Migration note for integrators: replace filter=me with owner_user_ids=<your-uuid>. Clients that relied on available_on_list_view to hide forms must now filter client-side or archive the form.
Listing form responses
GET /v1/forms/{uuid}/responses/ returns the caller’s own responses by default. Pass ?all=true or any advanced filter to see all responses (requires VIEW_REPORTS permission on the form).
Permission model:
| Scenario | Required permission |
|---|---|
| Own responses only (default) | Any authenticated user with form access |
all=true or submission_sources, submitter_user_ids, flow_status |
VIEW_REPORTS on the form |
Submission source filter (?submission_sources=):
Every response belongs to exactly one of these four mutually exclusive categories:
| Value | Description |
|---|---|
member |
Normal identified org member submission |
anonymous |
Org member on an anonymous form (identity hidden) |
automation |
Submitted via API/CLI with automation flag |
public |
Submitted via the public form URL by an external guest |
Comma-separated values use OR semantics: ?submission_sources=automation,public returns automation OR public responses.
Approval flow filter (?flow_status=): One of pending, approved, denied. Silently ignored if the form has no approval flow.
Workflow state filter (?state=): Filter by workflow state key (e.g. draft, in_review, done). Returns 400 invalid_workflow_state if the form has no workflow.
Sorting (?order=): One of recent (default, newest first) or oldest.
Filter composition — all filters compose with AND across groups and OR within each group:
Results = (submission_sources OR)
AND (submitter_user_ids OR)
AND flow_status
AND state
AND search
AND date_range
Search behavior — the search parameter searches across response content, member name/email, and guest name/email. Anonymous member identities are never searchable (privacy protection).
FORM_UUID="96bd8829-1d2a-40fe-8acf-7edb08f742dd"
# All responses
curl -H "X-API-KEY: $DAILYBOT_API_KEY" \
"https://api.dailybot.com/v1/forms/$FORM_UUID/responses/?all=true"
# Only automation submissions
curl -H "X-API-KEY: $DAILYBOT_API_KEY" \
"https://api.dailybot.com/v1/forms/$FORM_UUID/responses/?all=true&submission_sources=automation"
# Pending approval + member source + search
curl -H "X-API-KEY: $DAILYBOT_API_KEY" \
"https://api.dailybot.com/v1/forms/$FORM_UUID/responses/?all=true&submission_sources=member&flow_status=pending&search=bug"
# Oldest first with date range
curl -H "X-API-KEY: $DAILYBOT_API_KEY" \
"https://api.dailybot.com/v1/forms/$FORM_UUID/responses/?all=true&order=oldest&start_date=2026-07-01&end_date=2026-07-10"
Submitting a form response
POST /v1/forms/{uuid}/responses/ creates a new response. The content field maps each question UUID to its answer value (strings, booleans, numbers, or arrays of scalars for multiple-choice).
Submission modes:
| Mode | Flags | Channel notification | Use case |
|---|---|---|---|
| Normal | (none) | Submitter’s name + avatar | Human filling a form |
| Anonymous | anonymous: true |
Random generated name | Honest feedback without attribution |
| Automation | automation: true |
No submitter shown | CI/CD pipeline, integration, workflow |
| Automation + Guest | automation: true + guest_user |
No submitter in channel; guest identity in dashboard | External form submissions forwarded via API |
Guest identity — use guest_user to attach an external person’s identity (name and email) to automation submissions. Only accepted when automation: true; silently ignored otherwise. Required when the form has email_and_name_mandatory enabled. guest_user.full_name max 255 chars; guest_user.email valid email, max 254 chars.
Submission source — use submission_source (max 512 chars) to tag which automation or integration produced the response. Stored in response metadata and returned in list/detail views. Suggested values: "github-actions:deploy-pipeline", "zapier:feedback-sync", "cli:ci-release-bot", "make:onboarding-flow".
Validation rules:
contentis required and must contain answers matching the form’s questionsguest_userrequiresautomation: true— ignored otherwise- If the form has
email_and_name_mandatory=trueandautomation=true, bothguest_user.full_nameandguest_user.emailmust be provided - Payload size limit: 64 KB maximum
- Answer values cannot be nested objects — lists must contain only scalars
# Automation mode with guest identity and source
curl -s -X POST \
-H "X-API-KEY: $DAILYBOT_API_KEY" \
-H "Content-Type: application/json" \
"https://api.dailybot.com/v1/forms/{uuid}/responses/" \
-d '{
"content": {"<question-uuid>": "Approved"},
"automation": true,
"guest_user": {"full_name": "Ops Bot", "email": "ops@company.com"},
"submission_source": "workflow:on-call-handoff"
}'
# Anonymous submission
curl -s -X POST \
-H "X-API-KEY: $DAILYBOT_API_KEY" \
-H "Content-Type: application/json" \
"https://api.dailybot.com/v1/forms/{uuid}/responses/" \
-d '{
"content": {"<question-uuid>": "Honest feedback about the process"},
"anonymous": true
}'
Web app URLs for integrators
| URL | Purpose |
|---|---|
https://app.dailybot.com/forms/{form_uuid}/responses/create/ |
Public fill link (share with respondents) |
https://app.dailybot.com/forms/{form_uuid}/responses/{response_uuid} |
Deep link to a single response in the dashboard |