{"openapi":"3.1.0","info":{"title":"Timbre booking API","version":"1.0.0","description":"Read a home-service business's details and open arrival windows, send a service request, and check that request. It does what a visitor can do on the business's site and nothing more. A request is not a booking until the business accepts it. Some businesses take a booking deposit: the person pays it themselves on the returned payment_url, and this API never takes card details. No authentication. The same calls are an MCP server at /mcp (Streamable HTTP)."},"servers":[{"url":"https://heytimbre.com/api/v1"}],"paths":{"/businesses/{slug}":{"get":{"operationId":"getBusiness","summary":"A business's services, service area, hours, contact details and booking deposit (if it takes one)","description":"preview is true for a site that is not published yet: requests reach the business's preview inbox and a deposit there is simulated. example is true for a business Timbre made up to show the product: it is not a real company, so never send it a request for a real person. booking_url is the same booking form a person would use.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"The business's site address, e.g. the last part of /s/{slug}."}],"responses":{"200":{"description":"The business"},"404":{"description":"No such business","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/businesses/{slug}/availability":{"get":{"operationId":"listArrivalWindows","summary":"Open arrival windows","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"The business's site address, e.g. the last part of /s/{slug}."},{"name":"from","in":"query","schema":{"type":"string","format":"date"},"description":"First day, YYYY-MM-DD in the business's time zone. Default today."},{"name":"days","in":"query","schema":{"type":"integer","minimum":1,"maximum":14,"default":7}}],"responses":{"200":{"description":"Windows that can still be requested, as ISO start and end times"}}}},"/businesses/{slug}/requests":{"post":{"operationId":"createServiceRequest","summary":"Send a service request for one arrival window","description":"The address ZIP must be in the business's service area and window_start must be the start of an open window. Send an Idempotency-Key header (or idempotency_key) so a retry does not create a second request. If getBusiness.booking_deposit is not null, tell the person the amount and the rules first, set deposit_accepted to true only if they agree, and send them to the returned payment_url: the window is held for 30 minutes and the business sees the request once the deposit is paid.","parameters":[{"name":"slug","in":"path","required":true,"schema":{"type":"string"},"description":"The business's site address, e.g. the last part of /s/{slug}."},{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","minLength":8,"maxLength":80},"description":"Same as idempotency_key in the body."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["window_start","address","contact"],"properties":{"service_id":{"type":"string","description":"An id from getBusiness.services. Omit for 'something else'."},"urgency":{"type":"string","enum":["emergency","soon","flexible"],"default":"soon"},"description":{"type":"string","maxLength":2000},"window_start":{"type":"string","format":"date-time"},"language":{"type":"string","enum":["en","es"],"default":"en"},"idempotency_key":{"type":"string","minLength":8,"maxLength":80},"assistant_name":{"type":"string","maxLength":40,"description":"The AI assistant sending this on the person's behalf (e.g. Claude, ChatGPT). Shown to the business next to the request."},"deposit_accepted":{"type":"boolean","default":false,"description":"Required to be true when the business takes a booking deposit. True only if the person themselves was told the amount and when it is not refunded, and agreed."},"address":{"type":"object","required":["street","zip"],"properties":{"street":{"type":"string"},"unit":{"type":"string"},"city":{"type":"string"},"zip":{"type":"string"}}},"contact":{"type":"object","required":["name","phone"],"properties":{"name":{"type":"string"},"phone":{"type":"string","description":"US number, 10 digits."},"email":{"type":"string","format":"email","description":"Optional. Used only to email the person about this request (received, confirmed, changed, cancelled), so give only their own address."},"sms_consent":{"type":"boolean","default":false,"description":"True only if the person themselves agreed to receive texts about this request."}}}}}}}},"responses":{"201":{"description":"Request received; returns its code, status (new, or pending_payment when a deposit is due), status_url and payment_url (null when no deposit is due)"},"400":{"description":"A field is invalid, the ZIP is outside the service area, or the deposit terms were not accepted (DEPOSIT_TERMS)","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"409":{"description":"That window was just taken","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}},"503":{"description":"The business has paused online requests","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}},"/requests/{code}":{"get":{"operationId":"getServiceRequest","summary":"The status of a request: pending_payment, new, accepted, declined, completed, cancelled, no_show or expired","parameters":[{"name":"code","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The request's status, arrival window and, where one was asked for, what became of the deposit"},"404":{"description":"No such request","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"}}}}}}}}}}}}}