{"openapi":"3.1.0","info":{"title":"Tfa9adni API","version":"1","description":"Tickets, status, clients and loyalty for one shop, plus signed webhooks. One key per shop, created in the app (Boutique › Intégrations)."},"servers":[{"url":"https://api.tfa9adni.com/v1"}],"security":[{"bearer":[]}],"components":{"securitySchemes":{"bearer":{"type":"http","scheme":"bearer","description":"tfk_live_… key"}},"responses":{"Error":{"description":"Error","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"const":false},"error":{"type":"object","properties":{"code":{"type":"string"},"message":{"type":"string"},"details":{}}}}}}}}},"schemas":{"Ticket":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"number":{"type":["integer","null"]},"number_label":{"type":["string","null"]},"state":{"enum":["workshop","ready","impossible","collected","abandoned"]},"outcome":{"enum":["ready","impossible",null]},"type":{"enum":["repair","prepare"]},"service":{"type":"string"},"item":{"type":["string","null"]},"description":{"type":["string","null"]},"items":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"label":{"type":"string"},"service":{"type":["string","null"]},"price_minor":{"type":["integer","null"]},"done":{"type":"boolean"}}}},"money":{"type":"object","properties":{"currency":{"type":["string","null"]},"decimals":{"type":"integer"},"price_minor":{"type":["integer","null"]},"deposit_minor":{"type":["integer","null"]},"remaining_minor":{"type":["integer","null"]},"before_minor":{"type":["integer","null"]}}},"quote":{"type":["object","null"]},"promised_at":{"type":["string","null"],"format":"date-time"},"delay":{"type":["object","null"]},"part":{"type":["object","null"]},"client":{"type":["object","null"],"properties":{"id":{"type":"string"},"display_name":{"type":["string","null"]}}},"client_phone":{"type":["string","null"]},"tracking_code":{"type":["string","null"],"description":"Readable tracking code, as printed and sent to the client (e.g. YRT-EFDE4)"},"tracking_url":{"type":["string","null"]},"photo_url":{"type":["string","null"]},"created_at":{"type":"string"},"updated_at":{"type":"string"},"ready_at":{"type":["string","null"]},"collected_at":{"type":["string","null"]},"abandoned_at":{"type":["string","null"]},"abandon_reason":{"enum":["uncollected","no_news",null],"description":"uncollected: ready and never picked up; no_news: left in the workshop without any change from the shop"},"notified_at":{"type":["string","null"]},"created_via":{"enum":["app","api"]},"external_ref":{"type":["string","null"]}}},"Client":{"type":"object","properties":{"id":{"type":"string"},"display_name":{"type":["string","null"]},"tickets_open":{"type":"integer"},"tickets_total":{"type":"integer"},"loyalty":{"type":["object","null"]}}},"Card":{"type":"object","properties":{"balance":{"type":"integer"},"lifetime":{"type":"integer"},"rewards_available":{"type":"integer"},"rewards_redeemed":{"type":"integer"},"updated_at":{"type":["string","null"]}}},"Event":{"type":"object","properties":{"id":{"type":"string"},"type":{"enum":["ticket.created","ticket.ready","ticket.impossible","ticket.reopened","ticket.collected","ticket.abandoned","client.notified","client.linked","quote.accepted","ping"]},"created_at":{"type":"string"},"api_version":{"type":"string"},"shop_id":{"type":"string"},"data":{"type":"object"}}}}},"paths":{"/shop":{"get":{"summary":"The shop behind the key (test the connection)","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"data":{"type":"object"}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/tickets":{"get":{"summary":"List tickets","parameters":[{"name":"state","in":"query","schema":{"type":"string"}},{"name":"number","in":"query","schema":{"type":"string"}},{"name":"client_id","in":"query","schema":{"type":"string"}},{"name":"phone","in":"query","schema":{"type":"string"}},{"name":"external_ref","in":"query","schema":{"type":"string"}},{"name":"created_after","in":"query","schema":{"type":"string"}},{"name":"created_before","in":"query","schema":{"type":"string"}},{"name":"updated_since","in":"query","schema":{"type":"string"}},{"name":"limit","in":"query","schema":{"type":"string"}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"data":{"type":"array","items":{"$ref":"#/components/schemas/Ticket"}}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}},"post":{"summary":"Create a ticket","parameters":[{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","maxLength":80}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["service"],"properties":{"type":{"enum":["repair","prepare"]},"service":{"type":"string"},"item":{"type":"string"},"description":{"type":"string"},"items":{"type":"array"},"client_id":{"type":"string"},"client_phone":{"type":"string"},"price_minor":{"type":"integer"},"deposit_minor":{"type":"integer"},"promised_at":{"type":"string","format":"date-time"},"external_ref":{"type":"string"}}}}}},"responses":{"200":{"description":"Replayed","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Ticket"}}}}}},"201":{"description":"Created","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Ticket"}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/tickets/by-number/{n}":{"get":{"summary":"Newest open ticket with this number","parameters":[{"name":"n","in":"path","required":true,"schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Ticket"}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/tickets/{id}":{"get":{"summary":"One ticket","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Ticket"}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/tickets/{id}/status":{"post":{"summary":"Ready, impossible, back to the workshop, collected","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"enum":["ready","impossible","workshop","collected"]}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Ticket"}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/tickets/{id}/notified":{"post":{"summary":"The client was told outside the app","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["channel"],"properties":{"channel":{"enum":["sms","whatsapp","call"]}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Ticket"}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/clients":{"get":{"summary":"A client the shop knows, by phone","parameters":[{"name":"phone","in":"query","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Client"}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/clients/{id}":{"get":{"summary":"One client","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"data":{"$ref":"#/components/schemas/Client"}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/clients/{id}/loyalty":{"get":{"summary":"Loyalty program and card","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"data":{"type":"object","properties":{"program":{"type":"object"},"card":{"$ref":"#/components/schemas/Card"}}}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/clients/{id}/loyalty/stamps":{"post":{"summary":"Add stamps","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","maxLength":80}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["count"],"properties":{"count":{"type":"integer","minimum":1,"maximum":10}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"data":{"type":"object"}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}},"/clients/{id}/loyalty/redeem":{"post":{"summary":"Use one reward","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","format":"uuid"}},{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","maxLength":80}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","const":true},"data":{"type":"object"}}}}}},"400":{"$ref":"#/components/responses/Error"},"401":{"$ref":"#/components/responses/Error"},"403":{"$ref":"#/components/responses/Error"},"404":{"$ref":"#/components/responses/Error"},"409":{"$ref":"#/components/responses/Error"},"429":{"$ref":"#/components/responses/Error"}}}}},"webhooks":{"ticket.created":{"post":{"summary":"ticket.created","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"ticket.ready":{"post":{"summary":"ticket.ready","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"ticket.impossible":{"post":{"summary":"ticket.impossible","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"ticket.reopened":{"post":{"summary":"ticket.reopened","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"ticket.collected":{"post":{"summary":"ticket.collected","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"ticket.abandoned":{"post":{"summary":"ticket.abandoned","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"client.notified":{"post":{"summary":"client.notified","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"client.linked":{"post":{"summary":"client.linked","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"quote.accepted":{"post":{"summary":"quote.accepted","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}},"ping":{"post":{"summary":"ping","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Event"}}}},"responses":{"200":{"description":"Any 2xx acknowledges the event"}}}}}}