Example: a classify function that sorts support tickets
Source: studio_guide("example-classify") (GET /api/studio/v1/guide/example-classify) rendered at origin/platform (1afd83f), synced 2026-09-28. Do not edit this page here; change the source and run yarn sync:studio.
Build this when each ticket, review or note must land in one of a few fixed buckets, fast and cheap. It sorts one text field into a closed label set and answers a label with a confidence.
Person-only stops: the first publish. A person with publish rights on functions (the owner or an admin) opens the Studio link that function_publish answers and confirms it. A token cannot confirm.
Files
function.json
{
"schema": "bicycle.function/v1",
"name": "demo_ticket_type",
"kind": "classify",
"title": "Sort a support ticket by type",
"mode": "sync",
"timeout_ms": 10000,
"input_schema": {
"type": "object",
"required": [
"text"
],
"properties": {
"text": {
"type": "string",
"maxLength": 4000
}
}
},
"classify": {
"text_field": "text",
"instructions": "Which team should handle this customer support ticket? billing: charges, refunds, invoices, payment methods. delivery: shipping, tracking, late or missing parcels. product: how the product works, defects, features. other: anything else.",
"labels": [
"billing",
"delivery",
"product",
"other"
]
},
"visibility": {
"audience": "private",
"expose": {
"apps": true,
"workflows": true,
"agents": false,
"mcp": false
}
},
"docs": {
"summary": "Sorts one support ticket into billing, delivery, product or other."
},
"capabilities": [],
"output_schema": {
"type": "object",
"properties": {
"label": {
"type": "string",
"enum": [
"billing",
"delivery",
"product",
"other"
]
},
"confidence": {
"type": "number"
}
}
}
}
labels is a list of names. Put what each label means in instructions. capabilities and output_schema are required. The answer also carries labels (a list) and probabilities (one per label).
Calls, in order
function_create(name="demo_ticket_type", title="Sort a support ticket by type"): the function exists, with no version yet.function_put_files(name="demo_ticket_type", files={"function.json": ...}): version 1, statevalidated.function_try(name="demo_ticket_type", n=1, input={"text": "I was charged twice for my order last week. Please refund the extra charge."}):{"label": "billing", "confidence": 1.0, ...}.function_try(name="demo_ticket_type", n=1, input={"text": "My parcel was due on Monday and tracking has not moved for five days."}):{"label": "delivery", "confidence": 1.0, ...}.function_try(name="demo_ticket_type", n=1, input={"text": "The app crashes every time I open the settings screen."}):{"label": "product", "confidence": 1.0, ...}. Each run takes under a second. Show the person the three labels and ask whether they match.function_publish(name="demo_ticket_type", n=1): "A person must confirm this in Studio before v1 ofdemo_ticket_typegoes live": a link to/<company>/apps/functions/demo_ticket_type?publish=v1, and who may confirm (the owner or an admin, signed in; a token cannot). Give the person the link and stop.
The same job as a workflow step (not run here)
To sort many rows at once, use a classify node in a workflow. Rows below threshold stay unlabelled for a person.
"ticket_type": {"kind": "classify",
"config": {"fields": ["text"], "instructions": "Which team should handle this customer support ticket?",
"labels": {"billing": "Charges, refunds, invoices", "delivery": "Shipping, tracking, late parcels",
"product": "How the product works, defects", "other": "Anything else"},
"threshold": 0.6, "keep": ["ticket_id"]},
"inputs": {"rows": "tickets"}, "outputs": {"rows": "typed"}}
Switch it off
function_disable(name="demo_ticket_type", reason="no longer needed")
Verified on preview 2026-09-28: function_create, function_put_files, function_try (3 runs), function_publish (refusal captured), function_disable ran; the workflow step was not run; invocation ids inv_01M3J6NA7DJNVFYT867MJSCQYZ, inv_01M3J6NBS6C0JV4JH1S1R1BY2F, inv_01M3J6ND11TVVD9SJME75XHWA6.
guide_version bb2461328de4