Message, ask for a quote or book a call with Surfing Dog, through its open-source inbox.
Maintain this server? Claim it
Call this server's tools from your browser. Nothing to install.
Requests go through mcptry because browsers can't call most MCP servers directly. Header values are sent to the server for that request only and are never stored or logged.
Tool list from our last check. Connect live to refresh it.
Accept another time the business proposed for a booking, its quote, its changes to an order, or a change it asks for to a confirmed booking or an accepted order (offer.kind change: the promise moves). This binds your person, so send terms_sha — offer.terms_sha from get_item_status — only after they said yes to offer.human, and offer_id (offer.id) so an answer to an offer since replaced does nothing. Without terms_sha nothing is booked: you get the terms to show them. An accepted quote becomes a confirmed booking or order (linked). A yes to a change that can no longer be made online goes to a person there instead (passed_on), and what was agreed stands.
The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored.
The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored.
The offer you answer: offer.id from get_item_status. If the business has replaced it since, nothing is done (409 offer_changed, with the current one).
The fingerprint of the terms your person said yes to: offer.terms_sha from get_item_status. Leave it out to be told the terms first; nothing is booked without it.
Capability secret returned when the item was created without an account.
Same key + same request = same answer. Required for agents.
This tool isn't marked read-only, so it may change something on the server or in an account you connected.
Tool list last changed Oct 27, 2026.
Accept another time the business proposed for a booking, its quote, its changes to an order, or a change it asks for to a confirmed booking or an accepted order (offer.kind change: the promise moves). This binds your person, so send terms_sha — offer.terms_sha from get_item_status — only after they said yes to offer.human, and offer_id (offer.id) so an answer to an offer since replaced does nothing. Without terms_sha nothing is booked: you get the terms to show them. An accepted quote becomes a confirmed booking or order (linked). A yes to a change that can no longer be made online goes to a person there instead (passed_on), and what was agreed stands.
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| item_id* | string | |
| offer_id | string | The offer you answer: offer.id from get_item_status. If the business has replaced it since, nothing is done (409 offer_changed, with the current one). |
| terms_sha | string | The fingerprint of the terms your person said yes to: offer.terms_sha from get_item_status. Leave it out to be told the terms first; nothing is booked without it. |
| access_token | string | Capability secret returned when the item was created without an account. |
| idempotency_key | string | Same key + same request = same answer. Required for agents. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"item_id"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"item_id": {
"type": "string",
"minLength": 1
},
"offer_id": {
"type": "string",
"maxLength": 64,
"minLength": 1,
"description": "The offer you answer: offer.id from get_item_status. If the business has replaced it since, nothing is done (409 offer_changed, with the current one)."
},
"terms_sha": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43}$",
"description": "The fingerprint of the terms your person said yes to: offer.terms_sha from get_item_status. Leave it out to be told the terms first; nothing is booked without it."
},
"access_token": {
"type": "string",
"maxLength": 200,
"minLength": 16,
"description": "Capability secret returned when the item was created without an account."
},
"idempotency_key": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Same key + same request = same answer. Required for agents."
}
}
}Counter-sign a receipt this item earned, so both sides hold it: a promise, a change both sides agreed to it (kind amended), how it ended, or a refund's. Read the item to find its receipts; then send a compact JWS signed with your own Ed25519 key — header {alg:'EdDSA', typ:'sdi-receipt-ack+jws', jwk:<your public jwk>}, payload {rcp:<receipt id>, sha:<base64url(SHA-256(receipt jws))>, iat:<unix seconds>}. The instance verifies it against the key you carry and keeps it. Acknowledging twice is harmless.
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| item_id* | string | |
| receipt | string | The receipt JWS being acknowledged, if you want the instance to check it is the one it holds. |
| receipt_id | string | The receipt to acknowledge, for an agent that signs this request (sdi-agent/1) with a key delegated to the pass reference it sends: the inbox forwards the signature to the network (ADR-017 §3.4). Send this or counter_signature. |
| access_token | string | Capability secret returned when the item was created without an account. |
Cancel an item you created. After the business's cancellation window, a confirmed booking is cancelled late where the business records late cancellations (it may count against the customer), and refused where it does not. A confirmed stay answers first with the fee under its policy and what is owed back (confirm): send its fee_sha once your person said yes.
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| reason | string | |
| fee_sha | string | A confirmed stay: the fingerprint of the cancellation fee your person saw (details.fee_sha of the 409 confirm_terms a cancel without it gets). |
| item_id* | string | |
| access_token | string | Capability secret returned when the item was created without an account. |
| idempotency_key | string |
Free start times for a service between two instants (at most 14 days). A time that has started, or that starts within the business's minimum notice, is not offered.
| Argument | Type | Description |
|---|---|---|
| to* | string | End of the window, at most 14 days after from. |
| from* | string | Start of the window to search, ISO 8601. |
| party_size | integer | |
| service_id* | string |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"service_id",
"from",
"to"
],
"properties": {
"to": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
"description": "End of the window, at most 14 days after from."
},
"from": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
"description": "Start of the window to search, ISO 8601."
},
"party_size": {
"type": "integer",
"maximum": 1000,
"minimum": 1
},
"service_id": {
"type": "string",
"minLength": 1
}
}
}Request a service at a time. Check availability first. A fixed-price service costs the business's price from list_services; a different totalPrice you send is only noted for the business. A priced booking binds your person only once they confirmed it: without terms_sha nothing is sent, and you get the summary to show them (confirm.summary, confirm.terms_sha); call again with that terms_sha on their clear yes. Returns the item and, if you have no account, an access_token.
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| contact | object | |
| message | string | |
| payload* | object | |
| terms_sha | string | The fingerprint of the terms your person confirmed (details.terms_sha of the 409 confirm_terms a priced request without it gets). Nothing is sent to the business without it when the request carries a price. |
| visit_for | object | Book this as the site visit for a request for a price you made: its item_id (and access_token). |
Order products. Prices are in minor units. A line naming a product (productId or sku) costs the business's price from list_products, and the total follows; a different price you send is only noted for the business. A line naming no product waits for the business to price it. A priced order binds your person only once they confirmed it: without terms_sha nothing is sent, and you get the summary to show them (confirm.summary, confirm.terms_sha); call again with that terms_sha on their clear yes.
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| contact | object | |
| message | string | |
| payload* | object | |
| terms_sha | string | The fingerprint of the terms your person confirmed (details.terms_sha of the 409 confirm_terms a priced request without it gets). Nothing is sent to the business without it when the request carries a price. |
| attachments | array |
Say no to another time or to changes the business proposed (the booking request or the order is closed) or to its quote. To a change it asks for to a confirmed booking or an accepted order, no keeps what was agreed; on a change your person asked for (requested_change), it takes that back. Add reason (and reason_code) for anything your person wants the business to know.
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| reason | string | Anything your person wants the business to know. |
| item_id* | string | |
| offer_id | string | The offer you answer: offer.id from get_item_status. If the business has replaced it since, nothing is done (409 offer_changed, with the current one). |
| reason_code | string | Why: price_sensitivity, timing_deferred, quantity, delivery, returns_policy or other. |
Name, time zone, currency, languages and the item types this business accepts, and where it takes any other kind instead (doors_elsewhere: each with its URL, and the platform it is on when there is one).
No arguments.
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {}
}The current state of an item you created, in the business's words: what it proposed and waits for your person to answer (offer, with its terms_sha), who it waits on, what they can do next, and the conversation so far (thread: the business's replies and your person's messages).
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| item_id* | string | |
| access_token | string | Capability secret returned when the item was created without an account. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"item_id"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"item_id": {
"type": "string",
"minLength": 1
},
"access_token": {
"type": "string",
"maxLength": 200,
"minLength": 16,
"description": "Capability secret returned when the item was created without an account."
}
}
}Orderable products with prices in minor units, each with its barcode (gtin, 14 digits) where it has one and whether it is in stock. ids: read the live price of products a network showed you, before your person agrees; gtin: the products with that barcode, in any of its lengths. The price here is the one that counts.
| Argument | Type | Description |
|---|---|---|
| q | string | |
| ids | array | Only these products, by id (at most 50): read the live price of what a network showed you. |
| gtin | string | Only products with this barcode (GTIN, EAN, UPC or ISBN), in any of its lengths. One that does not read as a barcode is refused. |
| limit | integer | |
| cursor | string |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"q": {
"type": "string",
"maxLength": 100
},
"ids": {
"type": "array",
"items": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"maxItems": 50,
"minItems": 1,
"description": "Only these products, by id (at most 50): read the live price of what a network showed you."
},
"gtin": {
"type": "string",
"maxLength": 32,
"minLength": 1,
"description": "Only products with this barcode (GTIN, EAN, UPC or ISBN), in any of its lengths. One that does not read as a barcode is refused."
},
"limit": {
"type": "integer",
"default": 50,
"maximum": 100,
"minimum": 1
},
"cursor": {
"type": "string",
"maxLength": 200
}
}
}Bookable services with duration and price. A price per person (price.per = person) is for each person in the booking: send partySize, and the total is the price times it.
| Argument | Type | Description |
|---|---|---|
| limit | integer | |
| cursor | string |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"properties": {
"limit": {
"type": "integer",
"default": 50,
"maximum": 100,
"minimum": 1
},
"cursor": {
"type": "string",
"maxLength": 200
}
}
}Answer what the business proposed with only what your person would change: another start_time (a booking: one of the free times check_availability lists; a quote request: the time it is for), other quantities for the lines of changes it suggested to an order (by index in offer.terms.lines; 0 drops one), another delivery_when, or how many (quantity) for a quote request. It goes back to the business as their request. On a confirmed booking or an accepted order it asks for a change to what was agreed (lines by index in the order's orderedItem), which stands until the business says yes. A price of their own is their answer only where get_business_profile says price_negotiable: total_price for a time it proposed (start_time optional), unit_price on lines of changes to an order; it goes back to the business, which takes it or answers. Otherwise — a price where the business sets its prices, on a quote, on something it does not haggle, or asked too often — it goes to a person there as their message, as do a note alone and a suggestion after a few rounds (passed_on): never refused, and what the business proposed, or what was agreed, still stands.
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| note | string | Anything your person wants the business to know. |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| terms* | object | Only what your person would change. |
Answer what the business asked about an item (get_item_status says it needs a detail). The item moves on; on any other item your details are kept as a message for the business.
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| details* | string | The answer to what the business asked. |
| item_id* | string | |
| access_token | string | Capability secret returned when the item was created without an account. |
| idempotency_key | string | Same key + same request = same answer. Required for agents. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"item_id",
"details"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"details": {
"type": "string",
"maxLength": 5000,
"minLength": 1,
"description": "The answer to what the business asked."
},
"item_id": {
"type": "string",
"minLength": 1
},
"access_token": {
"type": "string",
"maxLength": 200,
"minLength": 16,
"description": "Capability secret returned when the item was created without an account."
},
"idempotency_key": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Same key + same request = same answer. Required for agents."
}
}
}Ask for a price on something custom. Creates a quote_request item.
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| contact | object | |
| message | string | |
| payload* | object | |
| attachments | array | Photos or plans of the job: JPEG, PNG, WebP or PDF, at most six of 10 MB each. Inline up to 4 MB each (8 MB a call), else by https address or upload_id. HEIC photos: send them as JPEG. Images are cleaned of where they were taken; a PDF is kept as sent. |
| idempotency_key | string | Same key + same request = same answer. Required for agents. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"payload"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"contact": {
"type": "object",
"properties": {
"name": {
"type": "string",
"maxLength": 200
},
"email": {
"type": "string",
"format": "email",
"pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
},
"phone": {
"type": "string",
"maxLength": 40
},
"locale": {
"type": "string",
"maxLength": 12
}
}
},
"message": {
"type": "string",
"maxLength": 20000
},
"payload": {
"type": "object",
"required": [
"itemOffered",
"description"
],
"properties": {
"job": {
"type": "object",
"properties": {
"site": {
"type": "object",
"properties": {
"geo": {
"type": "object",
"required": [
"latitude",
"longitude"
],
"properties": {
"latitude": {
"type": "number",
"maximum": 90,
"minimum": -90
},
"longitude": {
"type": "number",
"maximum": 180,
"minimum": -180
}
},
"description": "The site's point, when you have it: a radius is checked against it."
},
"address": {
"type": "object",
"properties": {
"postalCode": {
"type": "string",
"maxLength": 20
},
"addressRegion": {
"type": "string",
"maxLength": 100
},
"streetAddress": {
"type": "string",
"maxLength": 200
},
"addressCountry": {
"type": "string",
"pattern": "^[A-Za-z]{2}$"
},
"addressLocality": {
"type": "string",
"maxLength": 100
}
}
},
"accessNotes": {
"type": "string",
"maxLength": 500,
"description": "Gate codes are never asked for: only how to find the way."
},
"propertyType": {
"enum": [
"home",
"business",
"other"
],
"type": "string"
}
}
},
"visit": {
"enum": [
"needed",
"not_needed",
"unsure"
],
"type": "string",
"default": "unsure"
},
"urgency": {
"enum": [
"emergency",
"within_24h",
"this_week",
"flexible"
],
"type": "string",
"default": "flexible"
},
"windows": {
"type": "array",
"items": {
"type": "object",
"required": [
"from",
"to"
],
"properties": {
"to": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"from": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
}
}
},
"maxItems": 3,
"minItems": 1
},
"budgetMax": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Minor units of the currency's own ISO 4217 exponent (minorUnits): 4500 is CA$45.00 or ₹45.00, ¥4,500 in JPY, 4.500 in KWD."
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
}
},
"description": "The job: urgency (emergency, within_24h, this_week, flexible), whether a visit comes first, the site (address, how to find the way, home or business), up to three windows that suit, and budgetMax for a range."
},
"budget": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
},
"quantity": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
},
"description": {
"type": "string",
"maxLength": 5000,
"minLength": 1
},
"itemOffered": {
"type": "object",
"required": [
"name"
],
"properties": {
"sku": {
"type": "string",
"maxLength": 100
},
"name": {
"type": "string",
"maxLength": 200,
"minLength": 1
},
"productId": {
"type": "string"
},
"serviceId": {
"type": "string"
}
}
},
"requestedFor": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"deliveryAddress": {
"type": "object",
"properties": {
"postalCode": {
"type": "string",
"maxLength": 20
},
"addressRegion": {
"type": "string",
"maxLength": 100
},
"streetAddress": {
"type": "string",
"maxLength": 200
},
"addressCountry": {
"type": "string",
"maxLength": 2,
"minLength": 2
},
"addressLocality": {
"type": "string",
"maxLength": 100
}
}
}
}
},
"attachments": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"required": [
"upload_id"
],
"properties": {
"upload_id": {
"type": "string",
"pattern": "^upl_[A-Za-z0-9_-]{16,48}$",
"description": "What POST /v1/uploads answered, within its hour."
}
}
},
{
"type": "object",
"required": [
"data_base64"
],
"properties": {
"name": {
"type": "string",
"maxLength": 200,
"description": "The file's name, for the business to recognise it."
},
"data_base64": {
"type": "string",
"maxLength": 5592412,
"minLength": 4,
"description": "The file's bytes in base64: JPEG, PNG, WebP or PDF, up to 4 MB (8 MB in one call)."
}
}
},
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"maxLength": 2048,
"description": "An https address the file can be fetched from, up to 10 MB."
},
"name": {
"type": "string",
"maxLength": 200
}
}
}
]
},
"maxItems": 6,
"description": "Photos or plans of the job: JPEG, PNG, WebP or PDF, at most six of 10 MB each. Inline up to 4 MB each (8 MB a call), else by https address or upload_id. HEIC photos: send them as JPEG. Images are cleaned of where they were taken; a PDF is kept as sent."
},
"idempotency_key": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Same key + same request = same answer. Required for agents."
}
}
}Once an order's goods reached your person: ask to send them back. reason faulty, not_as_described or wrong_item (the legal guarantee: it costs them nothing), or changed_mind (a withdrawal while the period runs, agreed at once; after it, a return the business answers under its own policy). lines: which, by index in orderedItem, and how many; all when left out. The return comes back as linked; get_item_status lists it under refunds.
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| note | string | |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| lines | array | Which lines of the order (by index in orderedItem), and how many of each; all of them when left out. |
| wants | string | What your person would like: a refund, an exchange, or credit. |
| reason* | string | Why: changed_mind, faulty, wrong_item, not_as_described or other. |
| item_id* | string |
Start a conversation, or reply on an item you own.
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| body* | string | |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| contact | object | |
| item_id | string | Reply on an existing item; omit to start a new conversation. |
| subject | string | |
| message_id | string | |
| access_token | string | Capability secret returned when the item was created without an account. |
| idempotency_key | string | Same key + same request = same answer. Required for agents. |
Instead of the time the business proposed, ask for another: start_time must be one of the free times check_availability lists (the end follows the service's length). The business confirms it or proposes again. On a confirmed booking it asks the business to move it (the end keeps the booking's length), and the booking stays as agreed until the business says yes. After a few rounds, or past the changes a booking may have, a person there answers it instead (passed_on).
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| note | string | |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| item_id* | string | |
| start_time* | string | The start your person would like instead: one of the free times check_availability lists. The end follows the service's length. |
| access_token | string | Capability secret returned when the item was created without an account. |
| idempotency_key | string |
When a result says identity.recognised is weak, the person gave the email of a customer the business knows. Call this with item_id and access_token to email them six digits; ask the person for the code and call it again with code. Then the business recognises them.
| Argument | Type | Description |
|---|---|---|
| code | string | The six digits the customer received. Omit to have them sent. |
| item_id* | string | |
| access_token | string | Capability secret returned when the item was created without an account. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"item_id"
],
"properties": {
"code": {
"type": "string",
"pattern": "^[0-9]{6}$",
"description": "The six digits the customer received. Omit to have them sent."
},
"item_id": {
"type": "string",
"minLength": 1
},
"access_token": {
"type": "string",
"maxLength": 200,
"minLength": 16,
"description": "Capability secret returned when the item was created without an account."
}
}
}Your person withdraws from their booking (one they paid for) or order, within the period the business states (withdrawal on get_item_status). Two steps: without confirm_withdrawal nothing is sent and you get the statement to show them (confirm.statement); send confirm_withdrawal: true on their yes. Before the goods went out the order ends and what was paid is refunded; once they reached your person, the goods come back (lines: only some of them) and are refunded. The business emails a copy. Never refused: past the period, or for something that cannot be returned, it goes to a person there instead (passed_on), or becomes a return under the business's own policy.
| Argument | Type | Description |
|---|---|---|
| key | string | The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored. |
| note | string | Anything your person wants to tell the business. |
| pass | string | The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored. |
| lines | array | Once the goods reached them: only these lines (by index in the order's orderedItem), and how many of each. |
| item_id* | string | |
| access_token |
| counter_signature | string | A compact JWS by the customer's agent, EdDSA, header carrying its Ed25519 public `jwk`, payload `{"rcp": "<receipt id>", "sha": "<base64url(SHA-256(receipt JWS))>", "iat": <unix seconds>}`. Or, for an agent that signs its requests instead (sdi-agent/1) and carries a pass reference, `receipt_id` alone. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"item_id"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"item_id": {
"type": "string",
"minLength": 1
},
"receipt": {
"type": "string",
"maxLength": 8192,
"minLength": 1,
"description": "The receipt JWS being acknowledged, if you want the instance to check it is the one it holds."
},
"receipt_id": {
"type": "string",
"maxLength": 64,
"minLength": 1,
"description": "The receipt to acknowledge, for an agent that signs this request (sdi-agent/1) with a key delegated to the pass reference it sends: the inbox forwards the signature to the network (ADR-017 §3.4). Send this or counter_signature."
},
"access_token": {
"type": "string",
"maxLength": 200,
"minLength": 16,
"description": "Capability secret returned when the item was created without an account."
},
"counter_signature": {
"type": "string",
"maxLength": 8192,
"minLength": 1,
"description": "A compact JWS by the customer's agent, EdDSA, header carrying its Ed25519 public `jwk`, payload `{\"rcp\": \"<receipt id>\", \"sha\": \"<base64url(SHA-256(receipt JWS))>\", \"iat\": <unix seconds>}`. Or, for an agent that signs its requests instead (sdi-agent/1) and carries a pass reference, `receipt_id` alone."
}
}
}| Same key + same request = same answer. Required for agents. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"item_id"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"reason": {
"type": "string",
"maxLength": 2000
},
"fee_sha": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43}$",
"description": "A confirmed stay: the fingerprint of the cancellation fee your person saw (details.fee_sha of the 409 confirm_terms a cancel without it gets)."
},
"item_id": {
"type": "string",
"minLength": 1
},
"access_token": {
"type": "string",
"maxLength": 200,
"minLength": 16,
"description": "Capability secret returned when the item was created without an account."
},
"idempotency_key": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Same key + same request = same answer. Required for agents."
}
}
}| attachments | array | Photos or plans of the job: JPEG, PNG, WebP or PDF, at most six of 10 MB each. Inline up to 4 MB each (8 MB a call), else by https address or upload_id. HEIC photos: send them as JPEG. Images are cleaned of where they were taken; a PDF is kept as sent. |
| idempotency_key | string | Same key + same request = same answer. Required for agents. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"payload"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"contact": {
"type": "object",
"properties": {
"name": {
"type": "string",
"maxLength": 200
},
"email": {
"type": "string",
"format": "email",
"pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
},
"phone": {
"type": "string",
"maxLength": 40
},
"locale": {
"type": "string",
"maxLength": 12
}
}
},
"message": {
"type": "string",
"maxLength": 20000
},
"payload": {
"type": "object",
"required": [
"reservationFor",
"startTime",
"endTime"
],
"properties": {
"notes": {
"type": "string",
"maxLength": 5000
},
"policy": {
"type": "object",
"required": [
"steps",
"after",
"noShow",
"zone"
],
"properties": {
"zone": {
"type": "string",
"maxLength": 64,
"minLength": 1,
"description": "The IANA zone the steps were dated in: the business's."
},
"after": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Minor units of the currency's own ISO 4217 exponent (minorUnits): 4500 is CA$45.00 or ₹45.00, ¥4,500 in JPY, 4.500 in KWD."
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
},
"description": "The fee after the last step, until the start."
},
"steps": {
"type": "array",
"items": {
"type": "object",
"required": [
"until",
"fee"
],
"properties": {
"fee": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Minor units of the currency's own ISO 4217 exponent (minorUnits): 4500 is CA$45.00 or ₹45.00, ¥4,500 in JPY, 4.500 in KWD."
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
},
"until": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
}
}
},
"maxItems": 6,
"description": "Cancelling before `until` costs `fee`; the steps are in order."
},
"noShow": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Minor units of the currency's own ISO 4217 exponent (minorUnits): 4500 is CA$45.00 or ₹45.00, ¥4,500 in JPY, 4.500 in KWD."
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
}
}
},
"deposit": {
"type": "object",
"required": [
"amount",
"refundable"
],
"properties": {
"dueBy": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"amount": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
},
"refundable": {
"type": "boolean"
}
}
},
"endTime": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"partySize": {
"type": "integer",
"maximum": 1000,
"minimum": 1
},
"startTime": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"resourceId": {
"type": "string"
},
"totalPrice": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
},
"personalised": {
"type": "object",
"required": [
"listPrice"
],
"properties": {
"says": {
"type": "string",
"maxLength": 200
},
"listPrice": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
}
}
},
"reservationFor": {
"type": "object",
"required": [
"serviceId",
"name"
],
"properties": {
"name": {
"type": "string",
"maxLength": 200,
"minLength": 1
},
"serviceId": {
"type": "string",
"minLength": 1
}
}
}
}
},
"terms_sha": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43}$",
"description": "The fingerprint of the terms your person confirmed (details.terms_sha of the 409 confirm_terms a priced request without it gets). Nothing is sent to the business without it when the request carries a price."
},
"visit_for": {
"type": "object",
"required": [
"item_id"
],
"properties": {
"item_id": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"access_token": {
"type": "string",
"maxLength": 200,
"minLength": 16,
"description": "Capability secret returned when the item was created without an account."
}
},
"description": "Book this as the site visit for a request for a price you made: its item_id (and access_token)."
},
"attachments": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"required": [
"upload_id"
],
"properties": {
"upload_id": {
"type": "string",
"pattern": "^upl_[A-Za-z0-9_-]{16,48}$",
"description": "What POST /v1/uploads answered, within its hour."
}
}
},
{
"type": "object",
"required": [
"data_base64"
],
"properties": {
"name": {
"type": "string",
"maxLength": 200,
"description": "The file's name, for the business to recognise it."
},
"data_base64": {
"type": "string",
"maxLength": 5592412,
"minLength": 4,
"description": "The file's bytes in base64: JPEG, PNG, WebP or PDF, up to 4 MB (8 MB in one call)."
}
}
},
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"maxLength": 2048,
"description": "An https address the file can be fetched from, up to 10 MB."
},
"name": {
"type": "string",
"maxLength": 200
}
}
}
]
},
"maxItems": 6,
"description": "Photos or plans of the job: JPEG, PNG, WebP or PDF, at most six of 10 MB each. Inline up to 4 MB each (8 MB a call), else by https address or upload_id. HEIC photos: send them as JPEG. Images are cleaned of where they were taken; a PDF is kept as sent."
},
"idempotency_key": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Same key + same request = same answer. Required for agents."
}
}
}| Photos or plans of the job: JPEG, PNG, WebP or PDF, at most six of 10 MB each. Inline up to 4 MB each (8 MB a call), else by https address or upload_id. HEIC photos: send them as JPEG. Images are cleaned of where they were taken; a PDF is kept as sent. |
| idempotency_key | string | Same key + same request = same answer. Required for agents. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"payload"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"contact": {
"type": "object",
"properties": {
"name": {
"type": "string",
"maxLength": 200
},
"email": {
"type": "string",
"format": "email",
"pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
},
"phone": {
"type": "string",
"maxLength": 40
},
"locale": {
"type": "string",
"maxLength": 12
}
}
},
"message": {
"type": "string",
"maxLength": 20000
},
"payload": {
"type": "object",
"required": [
"orderedItem",
"totalPrice"
],
"properties": {
"tip": {
"type": "object",
"properties": {
"amount": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Minor units of the currency's own ISO 4217 exponent (minorUnits): 4500 is CA$45.00 or ₹45.00, ¥4,500 in JPY, 4.500 in KWD."
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
},
"percent": {
"type": "integer",
"maximum": 50,
"minimum": 0
}
}
},
"notes": {
"type": "string",
"maxLength": 5000
},
"fulfil": {
"type": "object",
"required": [
"method"
],
"properties": {
"fee": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Minor units of the currency's own ISO 4217 exponent (minorUnits): 4500 is CA$45.00 or ₹45.00, ¥4,500 in JPY, 4.500 in KWD."
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
},
"geo": {
"type": "object",
"required": [
"latitude",
"longitude"
],
"properties": {
"latitude": {
"type": "number",
"maximum": 90,
"minimum": -90
},
"longitude": {
"type": "number",
"maximum": 180,
"minimum": -180
}
},
"description": "The delivery address's point, when you have it: a ring zone is checked against it."
},
"slot": {
"type": "object",
"required": [
"start"
],
"properties": {
"end": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"start": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
}
}
},
"zone": {
"type": "object",
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"maxLength": 60
}
}
},
"etaMin": {
"type": "integer",
"maximum": 1440,
"minimum": 0
},
"method": {
"enum": [
"pickup",
"delivery",
"dine_in"
],
"type": "string"
}
}
},
"kitchen": {
"type": "object",
"required": [
"instant",
"hold"
],
"properties": {
"hold": {
"type": "array",
"items": {
"enum": [
"allergens_unconfirmed",
"over_cap",
"made_to_order",
"owner_accepts"
],
"type": "string"
},
"maxItems": 4
},
"instant": {
"type": "boolean"
}
}
},
"delivery": {
"type": "object",
"required": [
"method"
],
"properties": {
"when": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"method": {
"enum": [
"pickup",
"delivery",
"digital"
],
"type": "string"
}
}
},
"progress": {
"type": "object",
"required": [
"stage",
"at"
],
"properties": {
"at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"etaAt": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
"description": "When it expects it ready, or at the door."
},
"stage": {
"enum": [
"preparing",
"ready",
"out_for_delivery"
],
"type": "string"
}
}
},
"totalPrice": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
},
"orderedItem": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"quantity",
"price"
],
"properties": {
"sku": {
"type": "string",
"maxLength": 100
},
"name": {
"type": "string",
"maxLength": 200,
"minLength": 1
},
"note": {
"type": "string",
"maxLength": 140
},
"brief": {
"type": "object",
"properties": {
"flavour": {
"type": "string",
"maxLength": 80,
"minLength": 1
},
"message": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "The writing on it, within the length the business allows."
},
"servings": {
"type": "integer",
"maximum": 500,
"minimum": 1
}
}
},
"price": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
},
"options": {
"type": "array",
"items": {
"type": "object",
"required": [
"groupId",
"choiceId"
],
"properties": {
"name": {
"type": "string",
"maxLength": 120
},
"groupId": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"portion": {
"enum": [
"whole",
"left",
"right"
],
"type": "string",
"description": "On an item made in halves: whole, left or right."
},
"choiceId": {
"type": "string",
"maxLength": 64,
"minLength": 1
},
"priceDelta": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": -9007199254740991,
"description": "Minor units of the currency's own ISO 4217 exponent (minorUnits): 4500 is CA$45.00 or ₹45.00, ¥4,500 in JPY, 4.500 in KWD."
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
}
}
},
"maxItems": 40
},
"quantity": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 1
},
"listPrice": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
},
"productId": {
"type": "string"
}
}
},
"maxItems": 200,
"minItems": 1
},
"personalised": {
"type": "object",
"required": [
"listPrice"
],
"properties": {
"says": {
"type": "string",
"maxLength": 200
},
"listPrice": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
}
}
},
"paymentMethod": {
"type": "string",
"maxLength": 60
},
"billingAddress": {
"type": "object",
"properties": {
"postalCode": {
"type": "string",
"maxLength": 20
},
"addressRegion": {
"type": "string",
"maxLength": 100
},
"streetAddress": {
"type": "string",
"maxLength": 200
},
"addressCountry": {
"type": "string",
"maxLength": 2,
"minLength": 2
},
"addressLocality": {
"type": "string",
"maxLength": 100
}
}
},
"shippingAddress": {
"type": "object",
"properties": {
"postalCode": {
"type": "string",
"maxLength": 20
},
"addressRegion": {
"type": "string",
"maxLength": 100
},
"streetAddress": {
"type": "string",
"maxLength": 200
},
"addressCountry": {
"type": "string",
"maxLength": 2,
"minLength": 2
},
"addressLocality": {
"type": "string",
"maxLength": 100
}
}
}
}
},
"terms_sha": {
"type": "string",
"pattern": "^[A-Za-z0-9_-]{43}$",
"description": "The fingerprint of the terms your person confirmed (details.terms_sha of the 409 confirm_terms a priced request without it gets). Nothing is sent to the business without it when the request carries a price."
},
"attachments": {
"type": "array",
"items": {
"anyOf": [
{
"type": "object",
"required": [
"upload_id"
],
"properties": {
"upload_id": {
"type": "string",
"pattern": "^upl_[A-Za-z0-9_-]{16,48}$",
"description": "What POST /v1/uploads answered, within its hour."
}
}
},
{
"type": "object",
"required": [
"data_base64"
],
"properties": {
"name": {
"type": "string",
"maxLength": 200,
"description": "The file's name, for the business to recognise it."
},
"data_base64": {
"type": "string",
"maxLength": 5592412,
"minLength": 4,
"description": "The file's bytes in base64: JPEG, PNG, WebP or PDF, up to 4 MB (8 MB in one call)."
}
}
},
{
"type": "object",
"required": [
"url"
],
"properties": {
"url": {
"type": "string",
"format": "uri",
"maxLength": 2048,
"description": "An https address the file can be fetched from, up to 10 MB."
},
"name": {
"type": "string",
"maxLength": 200
}
}
}
]
},
"maxItems": 6,
"description": "Photos or plans of the job: JPEG, PNG, WebP or PDF, at most six of 10 MB each. Inline up to 4 MB each (8 MB a call), else by https address or upload_id. HEIC photos: send them as JPEG. Images are cleaned of where they were taken; a PDF is kept as sent."
},
"idempotency_key": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Same key + same request = same answer. Required for agents."
}
}
}| access_token |
| string |
| Capability secret returned when the item was created without an account. |
| idempotency_key | string | Same key + same request = same answer. Required for agents. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"item_id"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"reason": {
"type": "string",
"maxLength": 2000,
"description": "Anything your person wants the business to know."
},
"item_id": {
"type": "string",
"minLength": 1
},
"offer_id": {
"type": "string",
"maxLength": 64,
"minLength": 1,
"description": "The offer you answer: offer.id from get_item_status. If the business has replaced it since, nothing is done (409 offer_changed, with the current one)."
},
"reason_code": {
"enum": [
"price_sensitivity",
"timing_deferred",
"quantity",
"delivery",
"returns_policy",
"other"
],
"type": "string",
"description": "Why: price_sensitivity, timing_deferred, quantity, delivery, returns_policy or other."
},
"access_token": {
"type": "string",
"maxLength": 200,
"minLength": 16,
"description": "Capability secret returned when the item was created without an account."
},
"idempotency_key": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Same key + same request = same answer. Required for agents."
}
}
}| item_id* |
| string |
| offer_id | string | The offer you answer: offer.id from get_item_status. If the business has replaced it since, nothing is done (409 offer_changed, with the current one). |
| reason_code | string | Why: price_sensitivity, timing_deferred, quantity, delivery, returns_policy or other. |
| access_token | string | Capability secret returned when the item was created without an account. |
| idempotency_key | string | Same key + same request = same answer. Required for agents. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"item_id",
"terms"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"note": {
"type": "string",
"maxLength": 2000,
"description": "Anything your person wants the business to know."
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"terms": {
"type": "object",
"properties": {
"lines": {
"type": "array",
"items": {
"type": "object",
"required": [
"index",
"quantity"
],
"properties": {
"index": {
"type": "integer",
"maximum": 199,
"minimum": 0
},
"quantity": {
"type": "integer",
"maximum": 1000000,
"minimum": 0
},
"unit_price": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
}
}
}
},
"maxItems": 200,
"description": "For changes the business suggested to an order: other quantities for its lines, by index in offer.terms.lines; 0 drops a line. unit_price, a price of your own for a line, only where the business's profile says price_negotiable."
},
"quantity": {
"type": "integer",
"maximum": 1000000,
"minimum": 1,
"description": "How many, for a quote request."
},
"party_size": {
"type": "integer",
"maximum": 1000,
"minimum": 1,
"description": "Another number of people."
},
"start_time": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
"description": "Another start: for a booking, one of the free times check_availability lists (the end follows the service's length); for a quote request, the time it is for."
},
"total_price": {
"type": "object",
"required": [
"value",
"currency"
],
"properties": {
"value": {
"type": "integer",
"maximum": 9007199254740991,
"minimum": 0
},
"currency": {
"type": "string",
"maxLength": 3,
"minLength": 3
}
},
"description": "A price of your own for a time the business proposed. Taken as your answer only where the business's profile says price_negotiable; otherwise it goes to a person there as your message, and what it proposed still stands."
},
"delivery_when": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
"description": "Another delivery date, for an order."
}
},
"description": "Only what your person would change."
},
"item_id": {
"type": "string",
"minLength": 1
},
"offer_id": {
"type": "string",
"maxLength": 64,
"minLength": 1,
"description": "The offer you answer: offer.id from get_item_status. If the business has replaced it since, nothing is done (409 offer_changed, with the current one)."
},
"reason_code": {
"enum": [
"price_sensitivity",
"timing_deferred",
"quantity",
"delivery",
"returns_policy",
"other"
],
"type": "string",
"description": "Why: price_sensitivity, timing_deferred, quantity, delivery, returns_policy or other."
},
"access_token": {
"type": "string",
"maxLength": 200,
"minLength": 16,
"description": "Capability secret returned when the item was created without an account."
},
"idempotency_key": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Same key + same request = same answer. Required for agents."
}
}
}| access_token | string | Capability secret returned when the item was created without an account. |
| idempotency_key | string | Same key + same request = same answer. Required for agents. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"item_id",
"reason"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"note": {
"type": "string",
"maxLength": 2000
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"lines": {
"type": "array",
"items": {
"type": "object",
"required": [
"index",
"quantity"
],
"properties": {
"index": {
"type": "integer",
"maximum": 199,
"minimum": 0
},
"quantity": {
"type": "integer",
"maximum": 1000000,
"minimum": 1
}
}
},
"maxItems": 200,
"description": "Which lines of the order (by index in orderedItem), and how many of each; all of them when left out."
},
"wants": {
"enum": [
"refund",
"exchange",
"credit"
],
"type": "string",
"description": "What your person would like: a refund, an exchange, or credit."
},
"reason": {
"enum": [
"changed_mind",
"faulty",
"wrong_item",
"not_as_described",
"other"
],
"type": "string",
"description": "Why: changed_mind, faulty, wrong_item, not_as_described or other."
},
"item_id": {
"type": "string",
"minLength": 1
},
"access_token": {
"type": "string",
"maxLength": 200,
"minLength": 16,
"description": "Capability secret returned when the item was created without an account."
},
"idempotency_key": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Same key + same request = same answer. Required for agents."
}
}
}{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"body"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"body": {
"type": "string",
"maxLength": 20000,
"minLength": 1
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"contact": {
"type": "object",
"properties": {
"name": {
"type": "string",
"maxLength": 200
},
"email": {
"type": "string",
"format": "email",
"pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
},
"phone": {
"type": "string",
"maxLength": 40
},
"locale": {
"type": "string",
"maxLength": 12
}
}
},
"item_id": {
"type": "string",
"minLength": 1,
"description": "Reply on an existing item; omit to start a new conversation."
},
"subject": {
"type": "string",
"maxLength": 500
},
"message_id": {
"type": "string",
"maxLength": 998,
"minLength": 1
},
"access_token": {
"type": "string",
"maxLength": 200,
"minLength": 16,
"description": "Capability secret returned when the item was created without an account."
},
"idempotency_key": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Same key + same request = same answer. Required for agents."
}
}
}| Same key + same request = same answer. Required for agents. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"item_id",
"start_time"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"note": {
"type": "string",
"maxLength": 2000
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"item_id": {
"type": "string",
"minLength": 1
},
"start_time": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d:[0-5]\\d(?:\\.\\d+)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$",
"description": "The start your person would like instead: one of the free times check_availability lists. The end follows the service's length."
},
"access_token": {
"type": "string",
"maxLength": 200,
"minLength": 16,
"description": "Capability secret returned when the item was created without an account."
},
"idempotency_key": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Same key + same request = same answer. Required for agents."
}
}
}| string |
| Capability secret returned when the item was created without an account. |
| idempotency_key | string | Same key + same request = same answer. Required for agents. |
| confirm_withdrawal | boolean | true once your person confirmed the statement you were shown. Left out, nothing is sent: you get the statement. |
{
"type": "object",
"$schema": "https://json-schema.org/draft/2020-12/schema",
"required": [
"item_id"
],
"properties": {
"key": {
"type": "string",
"maxLength": 200,
"description": "The person's key (sdkey1_…), if that is all you have: it is exchanged once for a pass, which comes back in identity.passes — keep the pass and send it next time instead. Never stored."
},
"note": {
"type": "string",
"maxLength": 2000,
"description": "Anything your person wants to tell the business."
},
"pass": {
"type": "string",
"maxLength": 1608,
"description": "The person's passes (sdpass1_…), space-separated, at most 8: presented to the network that issued each, so the business recognises the customer. Or send them in the Sdi-Pass header. Never stored."
},
"lines": {
"type": "array",
"items": {
"type": "object",
"required": [
"index",
"quantity"
],
"properties": {
"index": {
"type": "integer",
"maximum": 199,
"minimum": 0
},
"quantity": {
"type": "integer",
"maximum": 1000000,
"minimum": 1
}
}
},
"maxItems": 200,
"description": "Once the goods reached them: only these lines (by index in the order's orderedItem), and how many of each."
},
"item_id": {
"type": "string",
"minLength": 1
},
"access_token": {
"type": "string",
"maxLength": 200,
"minLength": 16,
"description": "Capability secret returned when the item was created without an account."
},
"idempotency_key": {
"type": "string",
"maxLength": 200,
"minLength": 1,
"description": "Same key + same request = same answer. Required for agents."
},
"confirm_withdrawal": {
"type": "boolean",
"description": "true once your person confirmed the statement you were shown. Left out, nothing is sent: you get the statement."
}
}
}