Fivexer continuously matches tasks to workers based on tags, skills, priority, and business rules. Unlike queue-based routers, there are no static queues — matching is declarative and reruns every time something changes.
Core entities
- Task — a unit of work (ticket, case, job). It carries
tags, an optionalpriority, geo constraints, and rich data (context, comments, attachments). - Worker — an agent or automaton that can accept tasks. Workers carry
tags, skills with proficiency, availability status, and a tentative queue of matched tasks. - Decision — the platform's explainable match record: who was considered, who won, and why.
Matching lifecycle
- A task is created with
POST /tasks. Its status isqueued. - The matcher evaluates every available worker against the task's tags and constraints.
- The best worker(s) receive the task in their tentative queue (
GET /workers/{id}/queue). - The platform emits a
task.matchedwebhook. - The worker (or an operator) calls
POST /tasks/{id}/acceptto move it toaccepted, orrejectto requeue it. - When done,
POST /tasks/{id}/completefinishes the task.
What decides the winner
- Tag overlap — task tags must be satisfied by the worker's tags/skills.
- Priority — higher-priority tasks are matched first.
- Hard vetoes — rules you define can forbid a match regardless of score (e.g., "agent_1 cannot take billing tasks on Fridays").
- Fairness mode — choose whether to prefer first-come, best-match, balanced load, or spread-work.
- Learning layer — optional feedback-driven weights that retune themselves from real outcomes.
To see the exact reasoning for any task, call GET /v1/decisions?taskId=....
Before you commit
Two dry runs let you check a decision without making one:
POST /v1/tasks/checkcreates and reserves nothing, so it is safe to call on every keystroke of a form.POST /v1/tasks/suggest-workersscores who would match, without creating a task.
Clocks, escalation, and parked work
A task that nobody accepts does not sit in the queue forever.
- The response clock runs from the moment a task is offered.
POST /v1/tasks/{id}/ackacknowledges an offer without starting work — it stops that clock only, and is not an accept. - Escalation is a ladder.
POST /v1/tasks/{id}/escalateadvances it; a response ofescalated: false, parked: truemeans the ladder is exhausted and the task has left matching. That flag is the only thing that says so. - Parked tasks are out of matching but recoverable — an exhausted ladder, an SLA park, or a
spent rejection budget.
GET /v1/tasks/parkedlists them;POST /v1/tasks/{id}/unparkresets the clocks that parked it. Reset them, or the next sweep parks it straight back. - Scheduled tasks are held by a
schedule.notBeforeand have not entered matching yet.GET /v1/tasks/scheduledis the only view of work booked but not started.
Overriding a decision
POST /v1/tasks/{id}/assign is the operator override — it hands a task to a specific worker.
Default validation still applies (paused, backlog full, veto, prior rejection); force bypasses
those, but never worker existence. The response's previousWorkerId is null when the task came
from the queue rather than from another worker.
A supervisor can do the same thing from the sv_ plane, scoped to
their own crew.