The base url of Fragment’s api is https://api.onfragment.com/api/v1. The API status is available at https://status.onfragment.com

Introduction

The Fragment public API does its best to follow RESTful conventions when possible. All requests must be made via HTTPS. It uses standard HTTP responses and verbs like GET, POST, PUT, PATCH, DELETE. All PUT requests are idempotent and can be used to upsert resources. For example, the first call to PUT /v1/tasks/1 will create a new task with id 1 and the second call will be a no-op. Request bodies and responses are in JSON format. It is recommended to include a User-Agent header in your requests to help us identify your application and provide better support. This also helps avoid issues with anti-DDoS rules that may block requests without proper user agent identification.

Authentication

You can generate as many API tokens as you want in the web app in Settings > Developers. Try to give a descriptive name to your tokens.
Revoking a token in the web panel will instantly block all requests using that token.Make sure to update your applications with new tokens before revoking old ones to avoid service interruptions.
Your API token uniquely identifies your account.
API tokens are sensitive credentials that provide access to your Fragment account. Keep them secure and never share them publicly.Store them as environment variables or in secure configuration files (vaults, etc.), and don’t put them in version control.
The token should be included in the Authorization header using Bearer authentication.
example.py
import requests

response = requests.get(
    "https://api.onfragment.com/api/v1/accounts/me",
    headers={
        "Authorization": f"Bearer {token}",
        "User-Agent": "acme/1.0",
        "Content-Type": "application/json",
    }
)
response.json()
Non-authenticated requests will return a 401 Unauthorized error.

Rate limiting

The API is rate limited to 60 requests per minute. If you exceed this limit, you will receive a 429 Too Many Requests error. Small bursts of requests are allowed but should be avoided.

Status codes

The following status codes are used by the API:
Status codeDescription
200OK
400Bad Request
401Unauthorized
403Forbidden
404Not Found
422Unprocessable Entity
429Too Many Requests
500Internal Server Error
502Bad Gateway
503Service Unavailable

Error handling

In case of errors, we recommend that you retry the request with exponential backoff. Good defaults are to retry up to 5 times with a minimum delay of a few seconds and up to ~15 seconds (see below). In python you can use the tenacity library to retry the request with exponential backoff.
import requests
from tenacity import retry, stop_after_attempt, wait_exponential

@retry(stop=stop_after_attempt(5), wait=wait_exponential(multiplier=1, min=4, max=15))
def get_tasks():
    response = requests.get("https://api.onfragment.com/api/v1/tasks")
    response.raise_for_status()
    return response

response = get_tasks()
Note that some errors should not be retried like 401 Unauthorized or 422 Unprocessable Entity.

Durability & reliability

Monitoring

In the unlikely event that the Fragment API is not available or any other infrastructure issue occurs, you need to ensure that your system is resilient and can recover from these issues. You can monitor API availability at https://status.onfragment.com. You should also implement monitoring in your system to alert you when the API is not available or when you exceed the rate limit.

Recommendations

Here are some recommendations:
  1. Make sure that your system logic is idempotent and can be safely re-tried without creating duplicate tasks, overriding statuses, or pushing outdated information.
  2. Use a durable execution engine like Temporal for your workflows.
  3. Alternatively, you can use a message queue to process the requests in the background and handle the retries at the queue level. Note that not all solutions guarantee at least once and / or at most once delivery.
  4. Have a manual retry mechanism to recover from a given point of time. For example, if you got some alerts of failed requests at 11:05, you should be able to manually re-sync all the updates from that point of time.
See below for a minimal solution to implement reliable retries.

Minimal solution

A minimal solution to implement durable requests is to add a dedicated table in your database to queue the requests. A background worker can poll the table at regular intervals and process the requests as well as retry failed requests. This strategy has the added benefit of being able to push tasks in bulk using the /tasks/batch endpoint further reducing load on your system and the API.
Request IDEndpointBodyStatusErrorRetry countLast retry
123e4567-e89b-12d3-a456-426614174000GET /v1/tasks400Bad Request02025-09-11T12:00:00.000Z
123e4567-e89b-12d3-a456-426614174001POST /v1/tasks400Bad Request12025-09-11T12:00:00.000Z
123e4567-e89b-12d3-a456-426614174002PUT /v1/tasks/123e4567-e89b-12d3-a456-42661417400020002025-09-11T12:00:00.000Z
123e4567-e89b-12d3-a456-426614174003DELETE /v1/tasks/123e4567-e89b-12d3-a456-426614174000400Bad Request02025-09-11T12:00:00.000Z
123e4567-e89b-12d3-a456-426614174004POST /v1/tasks

Data types

Dates

We follow the ISO8601 standard with time zone information. Example 2023-07-28T03:39:51.140537+00:00
example.py
from datetime import datetime, timezone

now = datetime.now(timezone.utc)
now.isoformat()  # '2023-07-28T03:44:17.276943+00:00'

UUIDs

The Fragment API uses UUIDs for unique identifiers. The uid field is used to store IDs. Example 123e4567-e89b-12d3-a456-426614174000 The ID can be included in request body to create or update resources like so
{
    "uid": "123e4567-e89b-12d3-a456-426614174000",
    "status": "TODO",
    "due_at": "2025-09-11T12:00:00.000Z",
    "fields": {
        "title": "Claim 123",
        "url": "https://backoffice.com/claims/123",
        "claim_id": "123", 
        "country": "FR"
    }
}
When creating a resource and you are responsible for generating the ID, you can include the uid field in the POST request body. Alternatively, you can use the PUT /v1/{resource}/{uid} endpoint to create or update a resource (idempotent)

Properties

Use snake_case for custom field attributes. Example first_name.

Custom fields

Some entities like tasks have a fields key that allows you to push custom fields. For example, a task might look like this:
{
    "uid": "123e4567-e89b-12d3-a456-426614174000",
    "status": "TODO",
    "due_at": "2025-09-11T12:00:00.000Z",
    "fields": {
        "title": "Task title",
        "url": "https://example.com",
        "custom_field": "value"
    }
}
Prefer using snake_case for custom field attributes though any valid JSON key is allowed. The API will accept any valid JSON.
No type validation is performed on the custom fields. You are responsible for ensuring the data type is consistent.
To configure how the custom fields behaved in the UX, see Configure the data model.

Expanding resources

Many endpoints support expanding the resource by including the expand parameter. When expanding the related resources, the API will return the related resources in the response. Example:
import requests

response = requests.post(
    "https://api.onfragment.com/api/v1/tasks/query",
    json={
        "condition": {
            "field": "claim_id",
            "operator": "==",
            "value": "123"
        },
        "expand": ["comments"]
    },
    headers={
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
        "User-Agent": "acme/1.0",
    }
)
will return
{
    "items": [
        {
            "uid": "123e4567-e89b-12d3-a456-426614174000",
            "status": "TODO",
            "due_at": "2025-09-11T12:00:00.000Z",
            "fields": {
                "title": "Claim 123",
                "url": "https://backoffice.com/claims/123",
                "claim_id": "123", 
                "country": "FR"
            },
            "comments": [
                {
                    "uid": "123e4567-e89b-12d3-a456-426614174001",
                    "text": "This is a comment"
                }
            ]
        }
    ]
}

Pagination

Some endpoints like GET /v1/tasks return a list of items. The API uses cursor-based pagination for efficient traversal of large datasets. Each paginated response includes metadata to help you navigate through the results.

Caveat

Not all endpoints support pagination at the moment. If the response self_cursor is not present, it means that paginating is not supported for this endpoint.
If you need pagination support on a specific endpoint, please reach out to us.

Parameters

  • limit - The maximum number of items to return (optional)
  • cursor - A cursor token to start pagination from (optional)

Response

Each paginated endpoint returns a response with the following structure:
{
  "items": [
    // ... your data items here
  ],
  "meta": {
    "limit": 50,
    "self_cursor": "eyJpZCI6IjEyMyJ9",
    "prev_cursor": "eyJpZCI6IjEwMCJ9",
    "next_cursor": "eyJpZCI6IjE1MCJ9",
  }
}
  • items - The list of items returned by the request
  • meta - The metadata for the pagination
    • limit - The maximum number of items to return
    • self_cursor - The cursor token for the current page
    • prev_cursor - The cursor token for the previous page
    • next_cursor - The cursor token for the next page
If there is no next page, the next_cursor will be empty.

Examples

example.py
import requests
import time

cursor = None  # Initial cursor is None

for _ in range(10):  # Maximum number of pages
    response = requests.get(
        "https://api.onfragment.com/api/v1/tasks",
        params={
            "limit": 100,
            "cursor": cursor,
        },
        headers={
            "Authorization": f"Bearer {token}",
            "Content-Type": "application/json",
            "User-Agent": "acme/1.0",
        }
    )
    data = response.json()
    cursor = data["meta"]["next_cursor"]
    if not cursor:
        break
    time.sleep(1)