Appearance
Assignment provider apps
An assignment provider is an app that decides who does a task: a cleaning marketplace, a maintenance dispatcher, a staffing service. The host designates your app for a task type (say, cleaning); when such a task is created, Stayblox hands the assignment to you, you pick a worker using your own data, and you write the result back over the API.
The golden rule: your credentials and endpoints live on your server; Stayblox holds only the interface. Core Stayblox contains no provider-specific code; everything below works for any marketplace through the public API. We use Turno as the concrete example, but nothing here is Turno-specific.
For a complete runnable server, see the reference app.
1. Declare your app (manifest)
Register as a remote app that reads and writes tasks, holds the act_as_assignment_provider capability, and subscribes to task.assignment_requested. In your app.toml:
toml
type = "remote"
scopes = ["read_tasks", "write_tasks"]
capabilities = ["act_as_assignment_provider"]
webhooks = ["task.assignment_requested"]
webhook_url = "https://your-app.example.com/stayblox/webhooks"Add register_task_types to capabilities if you also define your own task types (with their own checklist and custom-field schema). The host consents to scopes and capabilities at install; both are stored on the install and checked on every call (see Scopes & capabilities).
2. Get designated for a task type
The host designates your app as the assignment provider for a task type in their dashboard (Operations → Task types → Assignment provider). From then on, every task of that type that the platform creates (typically via a host-configured rule, e.g. "on checkout, create a cleaning task") is routed to you for assignment.
3. Receive the assignment request (platform → app)
When such a task is created, Stayblox POSTs a task.assignment_requested webhook to your webhook_url. The request is HMAC-signed; verify it before acting (see Signing & security). The envelope's resource identifies the task:
json
{
"event_id": "01J…",
"topic": "task.assignment_requested",
"occurred_at": "2026-06-27T11:00:00Z",
"api_version": "2026-01",
"team": "8cs3o-qe",
"resource": {
"type": "task",
"id": 42,
"task_type": "cleaning",
"canonical_status": "open",
"property_id": 3,
"booking_id": 88,
"due_at": "2026-06-27T11:00:00Z"
}
}Fetch full task state any time with task(id) (read_tasks). Now schedule a worker on your side; Turno calls its own scheduling API on its own server. Stayblox never sees how you pick; it only sees the assignment you write back.
4. Write the assignment back (app → platform)
Call taskAssign with your bearer token to record the assignee. This needs the act_as_assignment_provider capability and moves the task OPEN → ASSIGNED. Store your own identifiers as namespaced custom fields so you can correlate later.
graphql
mutation Assign($id: ID!, $name: String!) {
taskAssign(input: { id: $id, assigneeType: "app", assigneeName: $name }) {
task { id canonicalStatus assigneeName }
userErrors { field message }
}
}bash
curl -s https://api.stayblox.com/developer/api/2026-01/graphql \
-H "Authorization: Bearer $STAYBLOX_APP_TOKEN" \
-H "Content-Type: application/json" -H "Accept: application/json" \
-d '{
"query": "mutation($id: ID!, $name: String!){ taskAssign(input:{ id:$id, assigneeType:\"app\", assigneeName:$name }){ task{ id canonicalStatus } userErrors{ message } } }",
"variables": { "id": "42", "name": "Sparkle Cleaners" }
}'Then attach your identifiers:
graphql
mutation Tag($id: ID!) {
taskSetCustomField(taskId: $id, namespace: "turno", key: "project_id", type: "string", value: "proj_42") {
task { id }
userErrors { message }
}
}5. Push status as the work progresses
As the job moves, transition the canonical status (and add photos/notes via checklist items or custom fields):
graphql
mutation Progress($id: ID!, $status: TaskStatus!) {
taskTransitionStatus(id: $id, status: $status) {
task { id canonicalStatus }
userErrors { field message }
}
}Walk ASSIGNED → IN_PROGRESS → COMPLETED as your worker accepts, starts, and finishes. Every transition is validated; illegal moves come back in userErrors.
The fallback
If you don't write an assignment back within the host's SLA window, Stayblox falls back to its own built-in assignment so the task never stalls, and your later write-back is then a no-op. Respond promptly; treat the request as time-bound.
Guest-readiness
A property becomes guest-ready when its cleaning task reaches COMPLETED / VERIFIED, derived purely from canonical status, never from a label you set. So the single thing that flips a unit to "ready" is your taskTransitionStatus to COMPLETED.
Worked example: a cleaning marketplace (Turno)
End to end, with zero Turno code in Stayblox:
- The host designates the Turno app as the cleaning provider and keeps the default "on checkout, create a cleaning task" rule.
- A guest checks out → the rule creates a cleaning task → Stayblox emits
task.assignment_requestedto Turno'swebhook_url. - Turno schedules a cleaner via its own API on its own server, then calls
taskAssign+taskSetCustomField(turno.project_id, …). - As the cleaner accepts → starts → finishes, Turno pushes
taskTransitionStatusthroughASSIGNED → IN_PROGRESS → COMPLETED, attaching photos as it goes. - The property flips to guest-ready off the canonical
COMPLETED.
Turno's API keys and endpoints stay on Turno's server throughout. Stayblox stores only the assignment and the custom fields Turno chose to write.
Checklist
- [ ] Manifest registered with
type: remote,scopes: [read_tasks, write_tasks],capabilities: [act_as_assignment_provider]. - [ ] Subscribed to
task.assignment_requested;webhook_urlset. - [ ] Webhook handler verifies the HMAC signature before acting.
- [ ] Assignment written back with
taskAssign(+ your ids viataskSetCustomField). - [ ] Status pushed with
taskTransitionStatusas work progresses. - [ ]
userErrorschecked on every mutation. - [ ] Write-back happens within the host's SLA window (or the internal fallback takes over).