{"openapi":"3.1.0","info":{"title":"IDOFO API","version":"1.0.0-beta","description":"IDOFO gives people and businesses their own AI assistant. This API exposes the same services the IDOFO web app uses: availability, booking, contacts, messages, leads, calls and the assistant itself.\n\nAn API key belongs to exactly one account. No endpoint accepts an account identifier, so there is no parameter that could reach another customer.","contact":{"name":"IDOFO developer centre","url":"/developers"}},"servers":[{"url":"/api/v1","description":"This installation"}],"security":[{"bearerAuth":[]}],"tags":[{"name":"Account"},{"name":"Scheduling"},{"name":"Contacts"},{"name":"Work","description":"Tasks, messages and leads"},{"name":"Calls"},{"name":"Business","description":"The facts the assistant is allowed to state"},{"name":"Assistant"},{"name":"Webhooks"}],"paths":{"/me":{"get":{"tags":["Account"],"summary":"Account, scopes and features for this key","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Me"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/account/export":{"get":{"tags":["Account"],"summary":"Export every record in this account","description":"Returns every record in this account as JSON, scoped to the tenant that owns the key. API key hashes and webhook signing secrets are omitted, and passwords are never included. Requires the account.export scope. There is no matching erase endpoint: closing an account is limited to a signed-in owner so that a leaked key cannot destroy a business.","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AccountExport"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/assistants":{"get":{"tags":["Assistant"],"summary":"List assistants","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssistantList"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/assistants/{id}":{"patch":{"tags":["Assistant"],"summary":"Update an assistant","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AssistantUpdate"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Assistant"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/availability":{"get":{"tags":["Scheduling"],"summary":"Real open times for a day","description":"Computed from opening hours, staff schedules, existing appointments, blocked time and holiday closures. Only times returned here may be offered to a caller.","parameters":[{"name":"date","in":"query","schema":{"type":"string","format":"date"},"description":"Defaults to today in the account timezone."},{"name":"serviceId","in":"query","schema":{"type":"string"}},{"name":"staffId","in":"query","schema":{"type":"string"}},{"name":"durationMinutes","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Availability"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/appointments":{"get":{"tags":["Scheduling"],"summary":"List appointments","parameters":[{"name":"from","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppointmentList"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Scheduling"],"summary":"Book an appointment","description":"Availability is re-checked inside the booking transaction, so concurrent bookings cannot collide.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AppointmentCreate"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"That time was taken while booking","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/appointments/{id}":{"get":{"tags":["Scheduling"],"summary":"Get an appointment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/appointments/{id}/reschedule":{"post":{"tags":["Scheduling"],"summary":"Move an appointment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["startsAt"],"properties":{"startsAt":{"type":"string","format":"date-time"},"durationMinutes":{"type":"integer"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/appointments/{id}/cancel":{"post":{"tags":["Scheduling"],"summary":"Cancel an appointment","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"reason":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Appointment"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/contacts":{"get":{"tags":["Contacts"],"summary":"List contacts","parameters":[{"name":"search","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"integer"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactList"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Contacts"],"summary":"Create a contact","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactCreate"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/contacts/{id}":{"get":{"tags":["Contacts"],"summary":"Get a contact","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Contacts"],"summary":"Update a contact","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ContactCreate"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Contact"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/tasks":{"get":{"tags":["Work"],"summary":"List tasks","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskList"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Work"],"summary":"Create a task","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TaskCreate"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Task"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/messages":{"get":{"tags":["Work"],"summary":"List messages","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageList"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Work"],"summary":"Create a message","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageCreate"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Message"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/leads":{"get":{"tags":["Work"],"summary":"List leads","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadList"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Work"],"summary":"Create a lead","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LeadCreate"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Lead"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/calls":{"get":{"tags":["Calls"],"summary":"List calls with summaries and outcomes","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CallList"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/calls/{id}":{"get":{"tags":["Calls"],"summary":"Get a call","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Call"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/calls/{id}/transcript":{"get":{"tags":["Calls"],"summary":"Get a transcript","description":"Requires the transcripts.read scope and the transcripts feature on the account plan.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Transcript"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/business":{"get":{"tags":["Business"],"summary":"Get the business profile","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Business"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"patch":{"tags":["Business"],"summary":"Update the business profile","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Business"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Business"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/services":{"get":{"tags":["Business"],"summary":"List services and prices","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceList"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Business"],"summary":"Create a service","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ServiceCreate"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Service"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/knowledge":{"get":{"tags":["Business"],"summary":"List answers the assistant may give","responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeList"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"post":{"tags":["Business"],"summary":"Add an answer","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/KnowledgeCreate"}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Knowledge"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/webhooks":{"post":{"tags":["Webhooks"],"summary":"Register a webhook endpoint","description":"Events: call.started, call.completed, appointment.created, appointment.rescheduled, appointment.canceled, appointment.completed, appointment.no_show, lead.created, lead.updated, message.created, task.created, task.completed, contact.created, needs_attention.created, assistant.updated, phone.number_claimed, phone.went_live, calendar.connected, calendar.disconnected. The signing secret is returned once.","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["url"],"properties":{"url":{"type":"string","format":"uri"},"events":{"type":"array","items":{"type":"string","enum":["call.started","call.completed","appointment.created","appointment.rescheduled","appointment.canceled","appointment.completed","appointment.no_show","lead.created","lead.updated","message.created","task.created","task.completed","contact.created","needs_attention.created","assistant.updated","phone.number_claimed","phone.went_live","calendar.connected","calendar.disconnected"]}},"description":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WebhookCreated"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/assistant/conversations":{"post":{"tags":["Assistant"],"summary":"Start a conversation with the assistant","requestBody":{"content":{"application/json":{"schema":{"type":"object","properties":{"callerName":{"type":"string"},"callerNumber":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationStarted"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/assistant/conversations/{id}/turns":{"post":{"tags":["Assistant"],"summary":"Send one caller turn and get the reply","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["message"],"properties":{"message":{"type":"string"}}}}}},"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Turn"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}},"/assistant/conversations/{id}/end":{"post":{"tags":["Assistant"],"summary":"End the conversation and get the summary","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Success","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ConversationEnded"}}}},"401":{"description":"Missing, unknown, wrong or revoked key","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"403":{"description":"Key lacks the required scope","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such record in this account","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"description":"Rate limited","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Tenant-scoped API key: idofo_live_<id>.<secret>. Scopes: assistants.read, assistants.write, contacts.read, contacts.write, appointments.read, appointments.write, calls.read, transcripts.read, tasks.read, tasks.write, messages.read, messages.write, leads.read, leads.write, knowledge.read, knowledge.write, business.read, business.write, webhooks.write, account.export."}},"schemas":{"Error":{"type":"object","properties":{"error":{"type":"object","properties":{"code":{"type":"string","enum":["unauthenticated","forbidden","not_found","invalid_request","conflict","rate_limited","entitlement_required","limit_exceeded","provider_unavailable","internal"]},"message":{"type":"string"}}}}},"AccountExport":{"type":"object","description":"A complete copy of one account. Contains no other customer.","properties":{"format":{"type":"string","example":"idofo.account-export.v1"},"exportedAt":{"type":"string","format":"date-time"},"account":{"type":"object"},"members":{"type":"array","items":{"type":"object"}},"records":{"type":"object","description":"One property per tenant-scoped table, each an array of rows.","additionalProperties":{"type":"array","items":{"type":"object"}}},"counts":{"type":"object","additionalProperties":{"type":"integer"}},"notes":{"type":"array","items":{"type":"string"}}}},"Me":{"type":"object","properties":{"account":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"type":{"type":"string","enum":["personal","business"]},"timezone":{"type":"string"},"plan":{"type":"string"}}},"scopes":{"type":"array","items":{"type":"string"}},"features":{"type":"array","items":{"type":"string"}}}},"Slot":{"type":"object","properties":{"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"label":{"type":"string","description":"Local time, ready to say out loud."},"staffId":{"type":"string","nullable":true}}},"Availability":{"type":"object","properties":{"date":{"type":"string","format":"date"},"timezone":{"type":"string"},"data":{"type":"array","items":{"$ref":"#/components/schemas/Slot"}}}},"Appointment":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"startsAt":{"type":"string","format":"date-time"},"endsAt":{"type":"string","format":"date-time"},"status":{"type":"string","enum":["scheduled","rescheduled","canceled","completed","no_show"]},"source":{"type":"string","enum":["web","assistant","api","import","demo"]},"contactId":{"type":"string","nullable":true},"serviceId":{"type":"string","nullable":true},"staffId":{"type":"string","nullable":true},"notes":{"type":"string","nullable":true}}},"AppointmentCreate":{"type":"object","required":["startsAt"],"properties":{"startsAt":{"type":"string","format":"date-time","description":"Must be a time returned by /availability."},"durationMinutes":{"type":"integer"},"title":{"type":"string"},"notes":{"type":"string"},"contactId":{"type":"string"},"serviceId":{"type":"string"},"staffId":{"type":"string"}}},"AppointmentList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Appointment"}}}},"Contact":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"phone":{"type":"string","nullable":true},"email":{"type":"string","nullable":true},"isVip":{"type":"boolean"},"tags":{"type":"array","items":{"type":"string"}},"notes":{"type":"string","nullable":true}}},"ContactCreate":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"},"isVip":{"type":"boolean"},"tags":{"type":"array","items":{"type":"string"}},"notes":{"type":"string"}}},"ContactList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Contact"}}}},"Task":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"status":{"type":"string","enum":["open","in_progress","done","canceled"]},"priority":{"type":"string","enum":["low","normal","high","urgent"]},"dueAt":{"type":"string","format":"date-time","nullable":true}}},"TaskCreate":{"type":"object","required":["title"],"properties":{"title":{"type":"string"},"description":{"type":"string"},"dueAt":{"type":"string","format":"date-time"},"priority":{"type":"string","enum":["low","normal","high","urgent"]},"contactId":{"type":"string"}}},"TaskList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Task"}}}},"Message":{"type":"object","properties":{"id":{"type":"string"},"fromName":{"type":"string"},"fromPhone":{"type":"string","nullable":true},"body":{"type":"string"},"urgency":{"type":"string","enum":["low","normal","high"]},"callbackRequested":{"type":"boolean"},"status":{"type":"string","enum":["new","read","handled","archived"]}}},"MessageCreate":{"type":"object","required":["fromName","body"],"properties":{"fromName":{"type":"string"},"fromPhone":{"type":"string"},"body":{"type":"string"},"reason":{"type":"string"},"urgency":{"type":"string","enum":["low","normal","high"]},"callbackRequested":{"type":"boolean"}}},"MessageList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Message"}}}},"Lead":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"serviceInterest":{"type":"string","nullable":true},"status":{"type":"string","enum":["new","contacted","booked","won","lost"]},"source":{"type":"string"}}},"LeadCreate":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"phone":{"type":"string"},"email":{"type":"string"},"serviceInterest":{"type":"string"},"estimatedValueCents":{"type":"integer"},"notes":{"type":"string"}}},"LeadList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Lead"}}}},"Call":{"type":"object","properties":{"id":{"type":"string"},"callerName":{"type":"string","nullable":true},"callerNumber":{"type":"string","nullable":true},"startedAt":{"type":"string","format":"date-time"},"durationSeconds":{"type":"integer"},"summary":{"type":"string","nullable":true},"outcome":{"type":"string"},"toolsUsed":{"type":"array","items":{"type":"string"}},"needsAttention":{"type":"boolean"},"appointmentId":{"type":"string","nullable":true},"leadId":{"type":"string","nullable":true},"messageId":{"type":"string","nullable":true}}},"CallList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Call"}}}},"Transcript":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object","properties":{"seq":{"type":"integer"},"speaker":{"type":"string","enum":["caller","assistant","system"]},"text":{"type":"string"},"toolName":{"type":"string","nullable":true},"at":{"type":"string","format":"date-time"}}}}}},"Business":{"type":"object","properties":{"legalName":{"type":"string"},"category":{"type":"string"},"website":{"type":"string","nullable":true},"phone":{"type":"string","nullable":true},"description":{"type":"string","nullable":true},"cancellationPolicy":{"type":"string","nullable":true},"afterHoursRule":{"type":"string","nullable":true},"escalationRule":{"type":"string","nullable":true}}},"Service":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"priceCents":{"type":"integer","nullable":true,"description":"Null means the assistant says it is quoted individually."},"durationMinutes":{"type":"integer"},"active":{"type":"boolean"}}},"ServiceCreate":{"type":"object","required":["name"],"properties":{"name":{"type":"string"},"price":{"type":"string","description":"Plain amount, e.g. \"149\". Omit for quoted individually."},"priceNote":{"type":"string"},"durationMinutes":{"type":"integer"},"description":{"type":"string"}}},"ServiceList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Service"}}}},"Knowledge":{"type":"object","properties":{"id":{"type":"string"},"question":{"type":"string"},"answer":{"type":"string"},"kind":{"type":"string"}}},"KnowledgeCreate":{"type":"object","required":["question","answer"],"properties":{"question":{"type":"string"},"answer":{"type":"string"},"kind":{"type":"string","enum":["faq","policy","fact","directions","other"]}}},"KnowledgeList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Knowledge"}}}},"Assistant":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"style":{"type":"string","enum":["professional","friendly","executive","warm","direct"]},"greeting":{"type":"string"},"status":{"type":"string","enum":["active","paused"]},"disclosure":{"type":"string","enum":["always","if_asked","never_required"]}}},"AssistantUpdate":{"type":"object","properties":{"name":{"type":"string"},"style":{"type":"string","enum":["professional","friendly","executive","warm","direct"]},"greeting":{"type":"string"},"status":{"type":"string","enum":["active","paused"]},"transferNumber":{"type":"string"}}},"AssistantList":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Assistant"}}}},"WebhookCreated":{"type":"object","properties":{"endpoint":{"type":"object","properties":{"id":{"type":"string"},"url":{"type":"string"},"events":{"type":"array","items":{"type":"string"}}}},"secret":{"type":"string","description":"Shown once. Used to verify the idofo-signature header."}}},"ConversationStarted":{"type":"object","properties":{"callId":{"type":"string"},"greeting":{"type":"string"},"assistant":{"type":"string"}}},"Turn":{"type":"object","properties":{"reply":{"type":"string"},"toolsUsed":{"type":"array","items":{"type":"string"},"description":"Backend tools that produced the facts in the reply."},"transferred":{"type":"boolean"},"needsAttention":{"type":"boolean"}}},"ConversationEnded":{"type":"object","properties":{"callId":{"type":"string"},"summary":{"type":"string"},"outcome":{"type":"string"},"durationSeconds":{"type":"integer"}}}}}}