API reference

Manage workflows, jobs and public shares programmatically. Every endpoint below carries samples in four languages and a panel that sends the request for real.

The base URL is https://takiflo.runasp.net. Every sample below is generated against it, and the panels send there unless you change the field.

Authentication

An API key is not a bearer token. You exchange it for a JWT that lasts 15 minutes, and that JWT authorises everything else. When it expires, post the key again. The key is the long-lived credential, so there is nothing else to store.

Get a key

  1. Sign in to TakiFlo.
  2. Go to API keys.
  3. Click Generate new key.
  4. Copy it. It is shown once.

Exchange it for a token

POST/api/apikeys/loginNo authentication
curl -X POST https://takiflo.runasp.net/api/apikeys/login \n  -H "Content-Type: application/json" \n  -d '{}'
{
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
}

Send it on every subsequent request:

Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...

Jobs

A job is a running instance of a workflow, holding its own copy of the graph and the state of every stage in it.

Create a job

POST/api/jobgraph
curl -X POST https://takiflo.runasp.net/api/jobgraph \n  -H "Authorization: Bearer $TAKIFLO_JWT" \n  -H "Content-Type: application/json" \n  -d '{
  "dagId": 45,
  "name": "Customer Onboarding - Instance 1",
  "jobId": 789,
  "autoRepeatOnFailure": false
}'
{
  "id": 123,
  "name": "Customer Onboarding - Instance 1",
  "remainingRepeats": null,
  "autoRepeatOnFailure": true,
  "serialization": {
    "id": 789,
    "name": "Customer Onboarding - Instance 1",
    "dag": { "nodes": [], "edges": [] }
  }
}

List jobs

GET/api/jobgraph
curl -X GET https://takiflo.runasp.net/api/jobgraph \n  -H "Authorization: Bearer $TAKIFLO_JWT"
[
  {
    "id": 123,
    "name": "Customer Onboarding - Instance 1",
    "remainingRepeats": 3,
    "autoRepeatOnFailure": true
  },
  {
    "id": 124,
    "name": "Data Pipeline - Run 42",
    "remainingRepeats": null,
    "autoRepeatOnFailure": false
  }
]

Get one job

Returns the job with its full graph: every stage, its state, and the edges between them.

GET/api/jobgraph/:id
curl -X GET https://takiflo.runasp.net/api/jobgraph/123 \n  -H "Authorization: Bearer $TAKIFLO_JWT"
{
  "id": 123,
  "name": "Customer Onboarding - Instance 1",
  "remainingRepeats": 3,
  "autoRepeatOnFailure": true,
  "dagId": 7,
  "dagVersion": 2,
  "currentDagVersion": 6,
  "serialization": {
    "id": 123,
    "name": "Customer Onboarding - Instance 1",
    "dag": {
      "nodes": [
        {
          "id": "1",
          "type": "StartNode",
          "state": 2,
          "name": "Start",
          "description": "Kick off the onboarding"
        },
        {
          "id": "2",
          "type": "RegularNode",
          "state": 1,
          "name": "Collect documents",
          "description": "Gather ID and proof of address",
          "instruction": "Upload both documents to the customer record.",
          "acceptanceCriteria": "Both documents are on file and dated within 3 months.",
          "estimatedDuration": 3600
        },
        { "id": "3", "type": "EndNode", "state": 0, "name": "End" }
      ],
      "edges": [
        { "sourceId": 1, "targetId": 2, "logicalOperator": 0 },
        { "sourceId": 2, "targetId": 3, "logicalOperator": 0 }
      ]
    }
  }
}

Errors:

StatusMeaning
404No job with that id.
403The job belongs to another tenant.

Delete a job

Permanently deletes it. Returns 204 No Content.

DELETE/api/jobgraph/:id
curl -X DELETE https://takiflo.runasp.net/api/jobgraph/123 \n  -H "Authorization: Bearer $TAKIFLO_JWT"

Moving a job along

Complete a stage

Marks a stage complete. This evaluates whatever depends on it, opens the stages that are now available, fires webhooks, and applies auto-repeat.

POST/api/jobgraph/Complete/Node
curl -X POST https://takiflo.runasp.net/api/jobgraph/Complete/Node \n  -H "Authorization: Bearer $TAKIFLO_JWT" \n  -H "Content-Type: application/json" \n  -d '{
  "jobGraphId": 123,
  "nodeId": 2,
  "state": 2
}'
// GET /api/jobgraph/123
const job = await response.json();
const stage = job.serialization.dag.nodes.find((n) => n.name === "Collect documents");
const nodeId = Number(stage.id);

Undo a stage

Reverts a stage to its previous state. Real processes go backwards.

POST/api/jobgraph/Undo/Node
curl -X POST https://takiflo.runasp.net/api/jobgraph/Undo/Node \n  -H "Authorization: Bearer $TAKIFLO_JWT" \n  -H "Content-Type: application/json" \n  -d '{
  "jobGraphId": 123,
  "nodeId": 2
}'

Reset a job

Returns a finished job to its starting state. Only works when the end stage is in a terminal state, success or failure. Optionally decrements the remaining repeats counter.

POST/api/jobgraph/:id/reset
curl -X POST https://takiflo.runasp.net/api/jobgraph/123/reset?decrement=true \n  -H "Authorization: Bearer $TAKIFLO_JWT"
{ "remainingRepeats": 2 }

Stage states

Every stage in a job is in one of four states.

ValueStateMeaning
0PendingWaiting on the stages before it.
1In progressAvailable to be worked on now.
2SuccessCompleted.
3FailureCompleted unsuccessfully.

Work queues

Hand a job, or a single stage of one, to a person in your organisation. Your own system decides who does what: look up the people, apply whatever routing logic you like, and enqueue the work. It appears in that person's queue when the workflow reaches it.

List the people you can assign to

Everyone in your organisation, with just enough to identify them. externalId is your own system's id for that person, if you set one. Match on that rather than on email, which changes.

GET/api/Users/directory
curl -X GET https://takiflo.runasp.net/api/Users/directory \n  -H "Authorization: Bearer $TAKIFLO_JWT"

Assign work

Omit nodeIndex, or send null, to hand over the whole job. nodeIndex is the stage's id, the same number you pass as nodeId when completing a stage.

POST/api/Assignments
curl -X POST https://takiflo.runasp.net/api/Assignments \n  -H "Authorization: Bearer $TAKIFLO_JWT" \n  -H "Content-Type: application/json" \n  -d '{
  "jobGraphId": 123,
  "nodeIndex": 3,
  "assigneeUserId": "a1b2c3",
  "note": "Needed before Friday"
}'

Refused with ASSIGNEE_NOT_IN_ORGANISATION if the user is not yours, and NO_SUCH_JOB_OR_STAGE if the job is not yours or has no such stage.

List, rescope and take back

GET/api/Assignments
curl -X GET https://takiflo.runasp.net/api/Assignments?jobGraphId=123&assigneeUserId=a1b2c3&includeDequeued=false \n  -H "Authorization: Bearer $TAKIFLO_JWT"

PATCH /api/Assignments/{id} takes assigneeUserId to reassign, nodeIndex to move it to a different stage, or assignWholeJob: true to widen it. That last one is sent explicitly, because a null nodeIndex already means "the whole job" and the absence of a value cannot carry both.

DELETE /api/Assignments/{id}?reason=... takes the work back. The record is kept, with who took it and why: a queue is a record of who was asked to do what, and a row that vanishes takes the answer with it.

A person's own queue

The caller's own queue, and nobody else's. It takes no user, so there is no parameter to change and see somebody else's work.

GET/api/WorkQueue
curl -X GET https://takiflo.runasp.net/api/WorkQueue \n  -H "Authorization: Bearer $TAKIFLO_JWT"

Each item carries a status: actionable when the work is waiting on them now, waiting when the workflow has not reached it yet, and done when it has been finished.

Metadata

Attach your own JSON to a job, or to one stage of one, and get it back on every webhook the job fires. TakiFlo never reads it. It is there so your systems can carry their own identifiers alongside the work instead of keeping a mapping table.

The rules

ShapeA JSON object. Arrays and bare values are refused.
SizeUp to 16 KB on a job and 4 KB on a stage, measured as UTF-8 bytes.
ReadingReturned on the job, and in webhook bodies. Never on a public share link.
SearchingNot indexed and not filterable. Use the job's own jobId field as your lookup key.

Set it when you create the job

Pass metadata to POST /api/jobgraph and the job carries it from the moment it exists.

{
  "dagId": 45,
  "name": "Order A-1",
  "metadata": { "orderId": "A-1", "customer": { "id": 7, "tier": "vip" } }
}

Merge keys into a job

Top-level keys only. A null value deletes its key, and a null body clears the whole payload.

PATCH/api/jobgraph/:id/metadata
curl -X PATCH https://takiflo.runasp.net/api/jobgraph/123/metadata \n  -H "Authorization: Bearer $TAKIFLO_JWT" \n  -H "Content-Type: application/json" \n  -d '{
  "metadata": {
    "stage": "packing"
  }
}'
{ "metadata": { "orderId": "A-1", "stage": "packing" } }

A nested object is replaced as a unit rather than merged into. Sending {"customer":{"id":8}} against a stored {"customer":{"id":7,"name":"Ada"}} leaves you with the id alone. That is deliberate, and it is what makes replacing one possible.

Replace a job's metadata

PUT/api/jobgraph/:id/metadata
curl -X PUT https://takiflo.runasp.net/api/jobgraph/123/metadata \n  -H "Authorization: Bearer $TAKIFLO_JWT" \n  -H "Content-Type: application/json" \n  -d '{
  "metadata": {
    "orderId": "A-2"
  }
}'

Metadata on one stage

Same two verbs, addressed by the stage's id from serialization.dag.nodes, the same number Complete/Node takes.

PATCH/api/jobgraph/:id/nodes/:nodeIndex/metadata
curl -X PATCH https://takiflo.runasp.net/api/jobgraph/123/nodes/2/metadata \n  -H "Authorization: Bearer $TAKIFLO_JWT" \n  -H "Content-Type: application/json" \n  -d '{
  "metadata": {
    "docId": "D-9"
  }
}'
{ "nodeId": 2, "metadata": { "docId": "D-9" } }

Errors:

CodeMeaning
metadata_missingThe body had no metadata field. Send an object, or null to clear.
metadata_not_an_objectAn array or a bare value was sent.
metadata_too_largeOver the cap. The response carries the limit in bytes.

Public sharing

Share a job with someone who has no account, so a customer or a stakeholder can watch progress without being invited into your organisation.

Create a share key

POST/api/publicjobgraphs
curl -X POST https://takiflo.runasp.net/api/publicjobgraphs \n  -H "Authorization: Bearer $TAKIFLO_JWT" \n  -H "Content-Type: application/json" \n  -d '{
  "jobGraphId": 123
}'
"a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6"

Read a shared job

No authentication. Anyone holding the key can read it, which is the point.

GET/api/publicjobgraphs/:keyNo authentication
curl -X GET https://takiflo.runasp.net/api/publicjobgraphs/a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6

List your share keys

GET/api/publicjobgraphs/by-tenant
curl -X GET https://takiflo.runasp.net/api/publicjobgraphs/by-tenant \n  -H "Authorization: Bearer $TAKIFLO_JWT"

Revoke a share key

Removes the key. The job is no longer reachable through the public endpoint.

DELETE/api/publicjobgraphs/:id
curl -X DELETE https://takiflo.runasp.net/api/publicjobgraphs/1 \n  -H "Authorization: Bearer $TAKIFLO_JWT"

Need Help?

We're here to support you every step of the way.

Documentation: Browse our guides or contact support.