Skip to content

API Conventions · Developers

Conventions that hold across every Dailybot API endpoint: identifiers, timestamps, casing, pagination, search, date range, and versioning.

Every endpoint in the Dailybot public API follows the same conventions for identifiers, timestamps, field casing, pagination, search, date range, and versioning. Learn them once here and every reference page will read exactly as you expect.

Identifiers

Every resource has a globally unique UUID (RFC 4122 v4). Depending on the model, the API returns it as uuid (Form, Form Response, User) or as id (Kudo, Check-in, Workflow) — in both cases the value is a UUID and can be used as a stable, opaque key in your integration.

Rule of thumb: if a resource has a dedicated UUID column separate from its internal primary key, the API returns uuid; if the primary key itself is a UUID, the API returns id. Both are UUIDs.

Resource Identifier field
Form uuid
Form Response uuid
Agent Report uuid (also returns id with the same value for backward compatibility)
Agent Message uuid (also returns id with the same value for backward compatibility)
User uuid
Kudo id (UUID)
Check-in (Follow-up) id (UUID)
Workflow id (UUID)

Timestamps

All timestamps are ISO-8601 in UTC with millisecond precision (e.g. 2026-07-02T14:33:19.412Z). Fields ending in _at are timestamps; fields ending in _date are date-only (YYYY-MM-DD). We never emit local-time strings.

Field casing

All JSON keys are snake_case (first_name, created_at). URL path segments are kebab-case (/pending-invitations/, /agent-reports/). Query parameters are snake_case (include_email, only_active).

Pagination

Every /v1/* list endpoint returns the same response envelope:

{
  "count": 152,
  "next": "https://api.dailybot.com/v1/...?page=2&page_size=50",
  "previous": null,
  "results": [ ... ]
}

Query parameters

Parameter Type Default Max Description
page integer 1 Page number (1-indexed)
page_size integer 25 100 Items per page. Values > 100 are silently clamped.

Legacy aliases (backwards-compatible)

Legacy param Maps to
limit page_size
offset Offset-based pagination

These aliases return the same envelope. next/previous URLs echo whichever style the caller used.

Removed opt-in pagination: The ?paginated=true query parameter and the X-Dailybot-Paginate: true request header are ignored. Every list endpoint always returns the envelope.

Response envelope fields

Field Type Description
count integer Total items matching the query (across all pages)
next string | null Full URL of the next page, or null if this is the last page
previous string | null Full URL of the previous page, or null if this is the first page
results array Items for this page (always an array, never null)

Paginated endpoints

Endpoint Default ordering
GET /v1/forms/ -created_at (newest first)
GET /v1/forms/{uuid}/responses/ -created_at
GET /v1/checkins/ -created_at
GET /v1/checkins/{uuid}/responses/ -created_at
GET /v1/kudos/ -id
GET /v1/kudos/organization/ -id
GET /v1/kudos/wall-of-fame/ -count (top contributors)
GET /v1/users/ full_name
GET /v1/teams/ name
GET /v1/workflows/ -created_at
GET /v1/pending-invitations/ -created_at
GET /v1/agent-messages/ -created_at

Iterating all pages

PAGE=1
while true; do
  RESP=$(curl -s "https://api.dailybot.com/v1/forms/?page=$PAGE&page_size=100" \
    -H "X-API-KEY: $DAILYBOT_API_KEY")
  echo "$RESP" | jq '.results[]'
  NEXT=$(echo "$RESP" | jq -r '.next')
  [ "$NEXT" = "null" ] && break
  PAGE=$((PAGE + 1))
done

A ?search=<term> parameter is available on list endpoints that expose text content. It performs a case-insensitive substring match applied after role scope — you can only search content you are already authorized to see. Composes with pagination and date-range filters.

Max query length: 256 characters. Over-length requests return 400 with code: "search_query_too_long".

Endpoint Fields searched
GET /v1/forms/?search=<term> Form name
GET /v1/checkins/?search=<term> Check-in name
GET /v1/forms/{uuid}/responses/?search=<term> Response content
GET /v1/checkins/{uuid}/responses/?search=<term> Response content
GET /v1/kudos/?search=<term> Kudo message
GET /v1/kudos/organization/?search=<term> Kudo message
GET /v1/workflows/?search=<term> Workflow name
GET /v1/followups/?search=<term> Check-in name (deprecated alias of /v1/checkins/)
GET /v1/users/?search=<term> Full name, email
curl "https://api.dailybot.com/v1/forms/?search=retro&page_size=10" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

Date range

A timezone-aware date range filter is available on every paginated endpoint.

Canonical parameters

Parameter Format Description
start_date YYYY-MM-DD Inclusive start — 00:00:00 in caller’s timezone
end_date YYYY-MM-DD Inclusive end — 23:59:59.999999 in caller’s timezone

Timezone behavior: Dates are interpreted in the authenticated user’s timezone (from their profile). Falls back to UTC when no timezone is set.

Also accepted (legacy aliases)

Legacy params Equivalent
date_start / date_end start_date / end_date
date_from / date_to start_date / end_date

Composition

Composes with ?search= and pagination:

curl "https://api.dailybot.com/v1/checkins/{uuid}/responses/?start_date=2026-07-01&end_date=2026-07-31&search=blocker&page_size=100" \
  -H "X-API-KEY: $DAILYBOT_API_KEY"

Error: Malformed dates return 400 with code: "invalid_date_range".

Case-insensitive filters

Enum-style query parameters accept any casing. For example, ?filter=kudos_received, ?filter=KUDOS_RECEIVED, and ?filter=Kudos_Received all resolve to kudos_received. Invalid values return 400 with code: "invalid_kudos_filter".

Versioning

The public API is versioned by URL prefix (/v1/). Additive changes (new endpoints, new optional fields, new enum values that fall back to defaults) may land at any time. Breaking changes ship behind a new prefix (/v2/) with a minimum 6-month sunset window on the prior version. See /developers/api-changelog for the running log.

Idempotency

All GET, PATCH, DELETE requests are idempotent by HTTP semantics — retrying them is safe. POST requests that create a resource are, in the general case, not idempotent; a naive retry after a network blip can create duplicate resources. When you retry after a 5xx or network error, always re-read the resource by its natural key (email, name, external id) first and only re-create if the read returns 404. Retry policy details live at /developers/errors#retry-policy.

null vs. missing

A field set to null explicitly means “this attribute has no value”. A field that is absent from the response means “the caller does not have permission to see it” or “the field was not requested via an include-flag”. Do not treat the two identically.