Skip to content

Error handling

The API returns errors in RFC 9457 (Problem Details for HTTP APIs) format.

Structure

{
  "type": "/problems/not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "No logs found for the specified parameters.",
  "instance": "/api/v1/dags/my-dag/runs"
}
Field Description
type Error type identifier
title Human-readable error title
status HTTP status code
detail Specific description of the problem in this request
instance Endpoint where the error occurred

Status codes

4xx — Client errors

Code Description
400 Bad Request The request has an incorrect format
401 Unauthorized Invalid, expired token or inactive session
403 Forbidden Valid token but insufficient permissions
404 Not Found Resource or data not found
422 Unprocessable Entity Invalid parameters or disallowed combination
429 Too Many Requests Request limit exceeded. See Retry-After in the response header

5xx — Server errors

Code Description
500 Internal Server Error Unexpected error. Try again after a few seconds.

Common errors

401 — Invalid token or inactive session

{
  "type": "/problems/unauthorized",
  "title": "Unauthorized",
  "status": 401,
  "detail": "Invalid token or inactive session.",
  "instance": "/api/v1/dags/my-dag/runs"
}

Solution: Obtain a new token and try again. The required header is:

Authorization: Bearer <token>

403 — Insufficient permissions

{
  "type": "/problems/forbidden",
  "title": "Forbidden",
  "status": 403,
  "detail": "The token does not contain the required company information.",
  "instance": "/api/v1/dags/my-dag/runs"
}

422 — Invalid parameters

{
  "type": "/problems/validation-error",
  "title": "Unprocessable Entity",
  "status": 422,
  "detail": "start_date is later than end_date.",
  "instance": "/api/v1/dags/my-dag/runs"
}

Common causes:

  • Incorrect date format (expected YYYY-MM-DD)
  • level in lowercase (must be ERROR, not error)
  • start_date later than end_date
  • Date range exceeding 7 days in run search
  • limit outside the allowed range for the endpoint

404 — No results

{
  "type": "/problems/not-found",
  "title": "Not Found",
  "status": 404,
  "detail": "No logs found for the specified filters.",
  "instance": "/api/v1/dags/my-dag/runs/2026-05-01/run-id/phases/extract/logs"
}

Note on empty queries

Run and log query endpoints return 200 OK with an empty list when there are no results. The 404 appears mainly on individual artifact or specific resource endpoints.


Best practices

import requests, time

def request_with_retry(url, headers, params):
    response = requests.get(url, headers=headers, params=params)

    if response.status_code == 401:
        headers["Authorization"] = f"Bearer {refresh_token()}"
        response = requests.get(url, headers=headers, params=params)

    elif response.status_code == 422:
        error = response.json()
        raise ValueError(f"Invalid parameters: {error['detail']}")

    elif response.status_code == 429:
        retry_after = int(response.headers.get("Retry-After", 60))
        time.sleep(retry_after)
        response = requests.get(url, headers=headers, params=params)

    elif response.status_code >= 500:
        time.sleep(2)
        response = requests.get(url, headers=headers, params=params)

    response.raise_for_status()
    return response.json()
async function fetchWithRetry(url, token, params) {
  const query = new URLSearchParams(params).toString();
  const headers = { Authorization: `Bearer ${token}` };

  let res = await fetch(`${url}?${query}`, { headers });

  if (res.status === 401) {
    token = await refreshToken();
    headers.Authorization = `Bearer ${token}`;
    res = await fetch(`${url}?${query}`, { headers });
  }

  if (res.status === 422) {
    const err = await res.json();
    throw new Error(`Invalid parameters: ${err.detail}`);
  }

  if (res.status === 429) {
    const retryAfter = parseInt(res.headers.get('Retry-After') || '60', 10);
    await new Promise(r => setTimeout(r, retryAfter * 1000));
    res = await fetch(`${url}?${query}`, { headers });
  }

  if (res.status >= 500) {
    await new Promise(r => setTimeout(r, 2000));
    res = await fetch(`${url}?${query}`, { headers });
  }

  if (!res.ok) throw new Error(`Error ${res.status}`);
  return res.json();
}