DailyAPI Documentationv1

Integration recipes

Production patterns for synchronization, PDF retrieval, retries, key rotation, and permissions.

View OpenAPI

Synchronize all customers

Use limit=100, follow next_cursor until it is null, and upsert by customer ID. The complete cURL, TypeScript, and Python loops in Pagination operate on /customers and check every response.

For an initial import, do not set time filters. Save a synchronization start timestamp before page 1, then use it for the next incremental run only after the full traversal succeeds.

Incrementally retrieve updated data

Customers, suppliers, leads, products, documents, payments, inventory levels, and tasks support updated_after. They also use a stable updated_at/ID cursor order.

type DailyPage<T> = { data: T[]; page: { next_cursor: string | null }; request_id: string };
const apiKey = process.env.DAILY_API_KEY;
if (!apiKey) throw new Error('DAILY_API_KEY is required');

async function* updatedSince<T>(resource: string, highWaterMark: string): AsyncGenerator<T> {
  let cursor: string | null = null;
  do {
    const url = new URL(`https://api.godaily.co.il/v1/${resource}`);
    url.searchParams.set('updated_after', highWaterMark);
    url.searchParams.set('limit', '100');
    if (cursor) url.searchParams.set('cursor', cursor);
    const response = await fetch(url, { headers: { Accept: 'application/json', Authorization: `Bearer ${apiKey}` } });
    const body = await response.json() as DailyPage<T> & { error?: { code: string } };
    if (!response.ok) throw new Error(`Daily API ${response.status} (${body.request_id}): ${body.error?.code}`);
    yield* body.data;
    cursor = body.page.next_cursor;
  } while (cursor);
}

for await (const customer of updatedSince<{ id: string; updated_at: string }>('customers', '2026-07-01T00:00:00.000Z')) {
  console.log(customer.id, customer.updated_at);
}

Use overlap plus idempotent upserts. Inventory movements support created_after, not updated_after, and are stable by created_at/ID. Periodically full-scan if your integration requires assurance beyond creation-only movement retrieval.

Retrieve suppliers, products, and documents

These commands fail on non-2xx responses and print the actual response envelope:

set -euo pipefail
: "${DAILY_API_KEY:?DAILY_API_KEY is required}"
for resource in suppliers products documents; do
  curl --fail-with-body --silent --show-error \
    --header "Authorization: Bearer ${DAILY_API_KEY}" \
    --header 'Accept: application/json' \
    "https://api.godaily.co.il/v1/${resource}?limit=100"
  printf '\n'
done

Each resource needs its own exact permission: ספקים, מוצרים ושירותים, and מסמכים.

Download a document PDF

List documents, select one with pdf_available: true, request GET /documents/{id}/pdf, and download the signed URL immediately. Validate HTTPS, HTTP status, content type, size, and the %PDF- signature. See PDF access for complete TypeScript and Python implementations.

Handle rate limiting safely

When 429 is returned, honor Retry-After: 1; for edge 503, honor Retry-After: 5. Add exponential backoff and random jitter, cap retries, and avoid retrying permanent 4xx responses. See the tested client pattern in Rate limits.

Rotate a key without downtime

  1. Rotate the existing key in Daily → API keys.
  2. Save the new one-time secret in your secret manager.
  3. Deploy it to every caller and make a health request.
  4. Confirm successful request IDs and key last-use behavior.
  5. Remove the old secret before its 24-hour grace period expires.

No public API operation rotates keys. Do not automate rotation by calling private application endpoints.

Troubleshoot permission failures

For 403 insufficient_permission:

  1. Record request_id and the requested path, never the Authorization header.
  2. Map the path to the permission table.
  3. Ask the primary business owner to edit that key in Daily.
  4. Retry once after the permission change.

Distinguish permission failures from api_access_inactive and ip_not_allowed; each requires a different configuration change.

On this page