# Migrate from TaskRouter

Fivexer and Twilio TaskRouter solve the same problem — route tasks to the right worker — but with different models. This guide maps TaskRouter concepts to Fivexer, shows before/after code, and gives a safe cutover playbook.

## Concept map

| Twilio TaskRouter | Fivexer | Notes |
| --- | --- | --- |
| Workspace | Workspace | Same name. Sign up gives you a sandbox workspace. |
| Task | Task | Direct equivalent. Create with `POST /tasks`. |
| Worker | Worker | Direct equivalent. Upsert with `POST /workers`. |
| TaskQueue | — | Fivexer has no queue objects. Matching is tag/skill-based and continuous. |
| Workflow | Tags + priority + vetoes + learning | Routing logic is declarative, not a YAML workflow. |
| Reservation | Decision + accept/reject/complete | `task.matched` webhook → accept/reject/complete lifecycle. |
| TaskChannel | Tags | Model voice/chat/email as tags or skills. |
| Activity | Worker availability | `available` flag, breaks, and backlog. |
| Events | Webhooks | `task.matched`, `task.accepted`, `task.rejected`, `task.completed`, etc. |

## Before/after: create and route a task

### Twilio

```
javascriptconst task = await client.taskrouter.v1.workspaces(workspaceSid).tasks.create({
    workflowSid,
    attributes: JSON.stringify({ skills: ['english', 'billing'] }),
    priority: 90,
});
```

### Fivexer (Python)

```
pythonfrom fivexer import Fivexer, CreateTask

client = Fivexer(base_url="https://api.fivexer.com", api_key="sk_test_...")
task = client.tasks.create(CreateTask(tags=["english", "billing"], priority=90))
```

## Before/after: accept a reservation

### Twilio

```
javascriptawait client.taskrouter.v1
    .workspaces(workspaceSid)
    .tasks(taskSid)
    .reservations(reservationSid)
    .update({ reservationStatus: 'accepted' });
```

### Fivexer

```
pythonclient.tasks.accept(task_id=task.id, worker_id="agent_1")
```

## Before/after: handle webhooks

### Twilio

```
javascript// Validate Twilio signature using your auth token
const valid = twilio.validateRequest(authToken, signature, url, params);
```

### Fivexer

```
pythonfrom fivexer import Webhook

event = Webhook.construct_event(payload=raw_body, header=signature_header, secret="whsec_...")
```

## Cutover playbook

1. **Shadow run** — for one week, create every TaskRouter task in Fivexer as well, but keep TaskRouter authoritative. Compare match decisions and worker acceptance rates.
2. **Migrate worker data** — upsert workers into Fivexer with the same tags/skills. Use `PATCH /workers/{id}` for proficiency and availability.
3. **Migrate webhooks** — point a copy of your event stream at a Fivexer receiver to test signature verification and event handling.
4. **Flip one workflow** — choose a low-risk task type, route it through Fivexer first, and fall back to TaskRouter only on error.
5. **Full cutover** — once metrics match or exceed TaskRouter, redirect task creation to Fivexer and drain TaskRouter.

## Where TaskRouter is still the better fit

If you are already on Twilio Flex, or you need native voice/SMS/chat with a platform SLA and don't want to run infrastructure, TaskRouter's tight Twilio integration remains an advantage. Fivexer is a routing platform, not a telephony platform.
