Skip to main content

Overview

You already have a ticket-like objects (Zendesk, Jira, internal back office, etc.)
In this scenario, your integration maintains an eventually consistent 1:1 mapping between Fragment and your existing tickets. Benefits:
  • Retain control over the ground truth
  • Clear 1:1 mapping between Fragment and your existing system
When controlling the full task lifecycle, ensure you:
  • Close tasks when they become irrelevant or are completed outside of Fragment
  • Update task fields to reflect the current state in your system
  • Handle edge cases like duplicate task creation and retries
  • Implement proper error handling and retry logic to maintain data consistency

Requirements

Objects

  • Task: the task object

Endpoints

Steps

The goal is to create a 1:1 mapping between your existing ticket objects and Fragment tasks and maintain that mapping up-to-date. At the minimum, you will need to:
  1. Decide on an ID mapping strategy to reliably link Fragment tasks to your existing tickets
  2. Create a task in Fragment when a ticket is created in your existing system
  3. Push relevant changes to Fragment when the ticket is updated in your existing system
In some cases, you might want to implement bi-directional sync, so that when a task is completed in Fragment, the ticket is updated in your existing system.
Fragment has experimental support for webhooks that enable bi-directional sync, please reach out to us if you need to implement this.
We assume that you have a ticket in your existing system that looks like this
ticket.json
{
    "id": 123,
    "country": "FR",
    "status": "open",
    "title": "Ticket 123",
}

1. Map IDs

There are two main options to manage the ID mapping between your existing ticket objects and Fragment tasks:
This method doesn’t require you to store the task ID in your system.
Generate a deterministic hash from your existing ticket ID (or other invariant fields that uniquely identify a ticket in a stable way). For example, our ticket ID is 123, we can generate a UUID like this:
utils.py
import hashlib
import uuid

def generate_uuid(s: str) -> uuid.UUID:
    """Convert a string to a uid."""
    m = hashlib.md5()
    m.update(s.encode("utf-8"))
    return uuid.UUID(m.hexdigest())


generate_uuid("tickets#123")
If you need to later retrieve the Fragment task from your existing ticket ID, ensure your hashing method is stable and deterministic. The same input should always generate the same UUID. Avoid using timestamps, random values, or other changing data in your hash generation.

B. Store the task ID in your system

This is a good option if you don’t want to generate a UUID for each task or if you want to explicitly store the task ID in your system. First, create the task on Fragment with a /POST request to the tasks endpoint.
{
    "uid": "123e4567-e89b-12d3-a456-426614174000",
    "status": "TODO",
    "due_at": "2025-09-11T12:00:00.000Z",
    "fields": { 
        "title": "Ticket 123",
        "url": "https://backoffice.com/tickets/123",
        "ticket_id": 123, 
        "country": "FR"
    }
}
Then, store the task ID in your system in a custom field. For example, if you are using SQL, you can do the following:
UPDATE claims SET fragment_task_uuid = '123e4567-e89b-12d3-a456-426614174000' WHERE id = 123;
This ensures that you can later retrieve the task from your existing ticket ID.

2. Create tasks

When you’re creating a task in Fragment that is related to an object in your system, it’s recommended to push information like the object id to Fragment as a custom field. Not only would this enable bi-directional sync, but it can also help troubleshooting issues as well as enable operators to easily search for the object in your existing system. For example,
sync.py
import requests

# Your existing ticket
ticket = {
    "id": 123,
    "country": "FR",
    "status": "open",
    "title": "Ticket 123",
}

response = requests.post(
    "https://api.onfragment.com/api/v1/tasks",
    json={
        # Optional: generate the task ID by hashing the ticket ID
        "uid": generate_uuid("123"),
        "fields": {
            "title": "Ticket 123",
            "url": "https://backoffice.com/tickets/123",
            "country": "FR",
            # Save the ticket ID in a custom field
            "ticket_id": 123,
        }
    },
    headers={
        "Authorization": f"Bearer {token}",
        "Content-Type": "application/json",
        "User-Agent": "acme/1.0",
    }
)
response.raise_for_status()
task = response.json()

# Optional: store the task ID in your system
save_task_uuid(task["uid"])
To avoid double task creation and guarantee idempotency, we recommend using the PUT /tasks/{uid} endpoint instead of POST /tasks.This requires that you generate a stable task ID that is consistent across retries.

3. Update tasks

If your existing object is updated, you need to propagate the changes to the corresponding task in Fragment. We assume that you have some change data capture (CDC) solution that will notify you when the ticket is updated. If you don’t have a CDC solution, an easy way to get started is to poll your existing system for updates at regular intervals (every 5 minutes, etc.). Then, you can use the PATCH /tasks/{uid} endpoint to update the task in Fragment.
update.py
import requests

def on_ticket_updated(ticket_id):
    # Get the ticket from your existing system
    ticket = get_ticket(ticket_id)

    # Get the task UUID from your system (stored or generated)
    task_uuid = get_task_uuid(ticket["id"])

    # Perform a PATCH request to update the task
    response = requests.patch(
        f"https://api.onfragment.com/api/v1/tasks/{task_uuid}",
        json={
           "status": "TODO" if ticket["status"] == "open" else "DONE"
        },
        headers={
            "Authorization": f"Bearer {token}",
            "Content-Type": "application/json",
            "User-Agent": "acme/1.0",
        }
    )
    response.raise_for_status()
For better throughput, you can use bulk upserts.

Eventual consistency

Depending on your use case, the synchronization between your existing system and Fragment might not be immediate and only eventually consistent. For example, you might have a cron that runs every 5 minutes to poll for changes in your existing system and update the corresponding task in Fragment. In that case, the task status on Fragment might be outdated by a few minutes. To avoid consistency issues and ghost tasks, you can set an eventual consistency delay in Fragment settings. This will temporarily hide newly created tasks in the backlog for this amount of time, to let enough time for any update to be propagated to Fragment that might close the task and result in unnecessary work.
I