Clients
GET /api/v1/clients clients:read
Llistar clients
Ordenats per id ascendent. Els clients esborrats per RGPD apareixen anonimitzats, amb erased_at informat.
Permís necessari: clients:read.
Consulta (query)
| Nom | Tipus | Obligatori | Descripció |
|---|
search | string | No | Cerca al nom, telèfon, email i NIF/CIF (mínim 2 caràcters). |
expand | string [vehicles] | No | Relacions opcionals que cal incloure. |
limit | integer · default 50 | No | Resultats per pàgina (1–200). |
cursor | string | No | Cursor opac retornat a next_cursor de la pàgina anterior. |
Exemple
curl "https://el-teu-taller.example/api/v1/clients" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Resposta
{
"data": [
{
"id": 1204,
"name": "Laura Gómez",
"phone": "+34600111222",
"phone_secondary": null,
"whatsapp_phone": null,
"email": "laura@ejemplo.com",
"billing_email": null,
"tax_id": "12345678Z",
"address": "C/ Mayor 12",
"city": "Barcelona",
"zip": "08001",
"province": "Barcelona",
"country": "ES",
"preferred_language": "es",
"preferred_contact_method": "whatsapp",
"vip": false,
"marketing_opt_out": false,
"channel_opt_out": {
"email": false,
"sms": false,
"whatsapp": false,
"call": false
},
"erased_at": null,
"vehicles": [
{
"id": 871,
"client_id": 1204,
"client": null,
"plate": "1234 KLM",
"vin": "VSSZZZ5FZJR123456",
"brand": "Seat",
"model": "León",
"variant": "1.5 TSI",
"year": 2019,
"registration_date": "2019-03-15",
"fuel": "Gasolina",
"transmission": "Manual",
"engine_code": "DADA",
"horsepower": 130,
"displacement": "1498",
"color_code": null,
"environmental_label": "C",
"km": 84500,
"itv_expiry_date": "2027-03-15",
"status": "activo"
}
]
}
],
"next_cursor": "aWQ6MTIzNA",
"has_more": true
}
POST /api/v1/clients clients:write
Crear un client
Mai no fusiona amb una fitxa existent: si el NIF/CIF, l'email o el telèfon ja són en un altre client respon 409 client_exists amb existing_id (o 200 amb aquest client si passes ?on_conflict=return_existing). El telèfon es desa com a la fitxa (Espanya en 9 dígits, altres països amb prefix) i l'email en minúscules; no es corregeixen errades. Les baixes comercials queden al registre de consentiments.
Permís necessari: clients:write.
Consulta (query)
| Nom | Tipus | Obligatori | Descripció |
|---|
on_conflict | string [error, return_existing] · default error | No | error (per defecte): 409 si ja existeix. return_existing: 200 amb el client existent. |
Capçaleres
| Nom | Tipus | Obligatori | Descripció |
|---|
Idempotency-Key | string | Sí | Clau única per operació (es recomana un UUID). Repetir-la amb el mateix cos en 24 h retorna la resposta desada amb Idempotent-Replay: true; amb un altre cos, 409 idempotency_conflict. |
Cos
{
"name": "Laura Gómez",
"phone": "600111222",
"phone_secondary": null,
"email": "laura@ejemplo.com",
"billing_email": null,
"tax_id": "12345678Z",
"address": "C/ Mayor 12",
"city": "Barcelona",
"zip": "08001",
"province": "Barcelona",
"country": "ES",
"preferred_language": "es",
"preferred_contact_method": "whatsapp",
"marketing_opt_out": false,
"channel_opt_out": {
"email": false,
"sms": false,
"whatsapp": false,
"call": false
}
}
Exemple
curl -X POST "https://el-teu-taller.example/api/v1/clients" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"name":"Laura Gómez","phone":"600111222","phone_secondary":null,"email":"laura@ejemplo.com","billing_email":null,"tax_id":"12345678Z","address":"C/ Mayor 12","city":"Barcelona","zip":"08001","province":"Barcelona","country":"ES","preferred_language":"es","preferred_contact_method":"whatsapp","marketing_opt_out":false,"channel_opt_out":{"email":false,"sms":false,"whatsapp":false,"call":false}}'
Resposta
{
"id": 1204,
"name": "Laura Gómez",
"phone": "+34600111222",
"phone_secondary": null,
"whatsapp_phone": null,
"email": "laura@ejemplo.com",
"billing_email": null,
"tax_id": "12345678Z",
"address": "C/ Mayor 12",
"city": "Barcelona",
"zip": "08001",
"province": "Barcelona",
"country": "ES",
"preferred_language": "es",
"preferred_contact_method": "whatsapp",
"vip": false,
"marketing_opt_out": false,
"channel_opt_out": {
"email": false,
"sms": false,
"whatsapp": false,
"call": false
},
"erased_at": null,
"vehicles": [
{
"id": 871,
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"plate": "1234 KLM",
"vin": "VSSZZZ5FZJR123456",
"brand": "Seat",
"model": "León",
"variant": "1.5 TSI",
"year": 2019,
"registration_date": "2019-03-15",
"fuel": "Gasolina",
"transmission": "Manual",
"engine_code": "DADA",
"horsepower": 130,
"displacement": "1498",
"color_code": null,
"environmental_label": "C",
"km": 84500,
"itv_expiry_date": "2027-03-15",
"status": "activo"
}
]
}
GET /api/v1/clients/{id} clients:read
Detall d'un client
Permís necessari: clients:read.
Paràmetres
| Nom | Tipus | Obligatori | Descripció |
|---|
id | integer | Sí | Id del client. |
Consulta (query)
| Nom | Tipus | Obligatori | Descripció |
|---|
expand | string [vehicles] | No | Relacions opcionals que cal incloure. |
Exemple
curl "https://el-teu-taller.example/api/v1/clients/1234" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Resposta
{
"id": 1204,
"name": "Laura Gómez",
"phone": "+34600111222",
"phone_secondary": null,
"whatsapp_phone": null,
"email": "laura@ejemplo.com",
"billing_email": null,
"tax_id": "12345678Z",
"address": "C/ Mayor 12",
"city": "Barcelona",
"zip": "08001",
"province": "Barcelona",
"country": "ES",
"preferred_language": "es",
"preferred_contact_method": "whatsapp",
"vip": false,
"marketing_opt_out": false,
"channel_opt_out": {
"email": false,
"sms": false,
"whatsapp": false,
"call": false
},
"erased_at": null,
"vehicles": [
{
"id": 871,
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"plate": "1234 KLM",
"vin": "VSSZZZ5FZJR123456",
"brand": "Seat",
"model": "León",
"variant": "1.5 TSI",
"year": 2019,
"registration_date": "2019-03-15",
"fuel": "Gasolina",
"transmission": "Manual",
"engine_code": "DADA",
"horsepower": 130,
"displacement": "1498",
"color_code": null,
"environmental_label": "C",
"km": 84500,
"itv_expiry_date": "2027-03-15",
"status": "activo"
}
]
}
PATCH /api/v1/clients/{id} clients:write
Modificar un client
Només canvien els camps enviats (null buida el camp). Es pot canviar l'email o el telèfon, i queda el valor anterior → nou a l'activitat del client amb el nom de la clau; emet client.updated. No es pot posar l'email, el telèfon o el NIF d'UNA ALTRA fitxa (409 client_exists). Les fitxes esborrades per RGPD responen 409 client_erased.
Permís necessari: clients:write.
Paràmetres
| Nom | Tipus | Obligatori | Descripció |
|---|
id | integer | Sí | Id del client. |
Capçaleres
| Nom | Tipus | Obligatori | Descripció |
|---|
Idempotency-Key | string | No | Clau única per operació (es recomana un UUID). Repetir-la amb el mateix cos en 24 h retorna la resposta desada amb Idempotent-Replay: true; amb un altre cos, 409 idempotency_conflict. |
Cos
{
"name": "Laura Gómez Ruiz",
"phone": "600111222",
"phone_secondary": null,
"email": "laura@ejemplo.com",
"billing_email": null,
"tax_id": "12345678Z",
"address": "C/ Mayor 12",
"city": "Barcelona",
"zip": "08001",
"province": "Barcelona",
"country": "ES",
"preferred_language": "es",
"preferred_contact_method": "whatsapp",
"marketing_opt_out": false,
"channel_opt_out": {
"email": false,
"sms": false,
"whatsapp": false,
"call": false
}
}
Exemple
curl -X PATCH "https://el-teu-taller.example/api/v1/clients/1234" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"name":"Laura Gómez Ruiz","phone":"600111222","phone_secondary":null,"email":"laura@ejemplo.com","billing_email":null,"tax_id":"12345678Z","address":"C/ Mayor 12","city":"Barcelona","zip":"08001","province":"Barcelona","country":"ES","preferred_language":"es","preferred_contact_method":"whatsapp","marketing_opt_out":false,"channel_opt_out":{"email":false,"sms":false,"whatsapp":false,"call":false}}'
Resposta
{
"id": 1204,
"name": "Laura Gómez",
"phone": "+34600111222",
"phone_secondary": null,
"whatsapp_phone": null,
"email": "laura@ejemplo.com",
"billing_email": null,
"tax_id": "12345678Z",
"address": "C/ Mayor 12",
"city": "Barcelona",
"zip": "08001",
"province": "Barcelona",
"country": "ES",
"preferred_language": "es",
"preferred_contact_method": "whatsapp",
"vip": false,
"marketing_opt_out": false,
"channel_opt_out": {
"email": false,
"sms": false,
"whatsapp": false,
"call": false
},
"erased_at": null,
"vehicles": [
{
"id": 871,
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"plate": "1234 KLM",
"vin": "VSSZZZ5FZJR123456",
"brand": "Seat",
"model": "León",
"variant": "1.5 TSI",
"year": 2019,
"registration_date": "2019-03-15",
"fuel": "Gasolina",
"transmission": "Manual",
"engine_code": "DADA",
"horsepower": 130,
"displacement": "1498",
"color_code": null,
"environmental_label": "C",
"km": 84500,
"itv_expiry_date": "2027-03-15",
"status": "activo"
}
]
}
Vehicles
GET /api/v1/vehicles vehicles:read
Llistar vehicles
Inclou l'últim quilometratge anotat i el venciment de la ITV.
Permís necessari: vehicles:read.
Consulta (query)
| Nom | Tipus | Obligatori | Descripció |
|---|
plate | string | No | Matrícula exacta (s'ignoren espais i guions). |
client_id | integer | No | Filtrar per client. |
status | string [activo, baja_temporal, baja] | No | Estat del vehicle. |
limit | integer · default 50 | No | Resultats per pàgina (1–200). |
cursor | string | No | Cursor opac retornat a next_cursor de la pàgina anterior. |
Exemple
curl "https://el-teu-taller.example/api/v1/vehicles" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Resposta
{
"data": [
{
"id": 871,
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"plate": "1234 KLM",
"vin": "VSSZZZ5FZJR123456",
"brand": "Seat",
"model": "León",
"variant": "1.5 TSI",
"year": 2019,
"registration_date": "2019-03-15",
"fuel": "Gasolina",
"transmission": "Manual",
"engine_code": "DADA",
"horsepower": 130,
"displacement": "1498",
"color_code": null,
"environmental_label": "C",
"km": 84500,
"itv_expiry_date": "2027-03-15",
"status": "activo"
}
],
"next_cursor": "aWQ6MTIzNA",
"has_more": true
}
POST /api/v1/vehicles vehicles:write
Donar d'alta un vehicle
Sempre a nom d'un client existent (client_id). La matrícula es normalitza (majúscules, sense espais ni guions). Si ja és a la fitxa d'UN ALTRE client: 409 vehicle_belongs_to_other_client. Si el mateix client ja la té: 409 vehicle_exists amb existing_id (o 200 amb ?on_conflict=return_existing).
Permís necessari: vehicles:write.
Consulta (query)
| Nom | Tipus | Obligatori | Descripció |
|---|
on_conflict | string [error, return_existing] · default error | No | error (per defecte) o return_existing. |
Capçaleres
| Nom | Tipus | Obligatori | Descripció |
|---|
Idempotency-Key | string | Sí | Clau única per operació (es recomana un UUID). Repetir-la amb el mateix cos en 24 h retorna la resposta desada amb Idempotent-Replay: true; amb un altre cos, 409 idempotency_conflict. |
Cos
{
"client_id": 1204,
"plate": "1234 KLM",
"vin": "VSSZZZ5FZJR123456",
"brand": "Seat",
"model": "León",
"variant": "1.5 TSI",
"year": 2019,
"registration_date": "2019-03-15",
"fuel": "Gasolina",
"transmission": "Manual",
"engine_code": "DADA",
"horsepower": 130,
"displacement": "1498",
"color_code": null,
"environmental_label": "C",
"itv_expiry_date": "2027-03-15",
"status": "activo"
}
Exemple
curl -X POST "https://el-teu-taller.example/api/v1/vehicles" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"client_id":1204,"plate":"1234 KLM","vin":"VSSZZZ5FZJR123456","brand":"Seat","model":"León","variant":"1.5 TSI","year":2019,"registration_date":"2019-03-15","fuel":"Gasolina","transmission":"Manual","engine_code":"DADA","horsepower":130,"displacement":"1498","color_code":null,"environmental_label":"C","itv_expiry_date":"2027-03-15","status":"activo"}'
Resposta
{
"id": 871,
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"plate": "1234 KLM",
"vin": "VSSZZZ5FZJR123456",
"brand": "Seat",
"model": "León",
"variant": "1.5 TSI",
"year": 2019,
"registration_date": "2019-03-15",
"fuel": "Gasolina",
"transmission": "Manual",
"engine_code": "DADA",
"horsepower": 130,
"displacement": "1498",
"color_code": null,
"environmental_label": "C",
"km": 84500,
"itv_expiry_date": "2027-03-15",
"status": "activo"
}
GET /api/v1/vehicles/{id} vehicles:read
Detall d'un vehicle
Permís necessari: vehicles:read.
Paràmetres
| Nom | Tipus | Obligatori | Descripció |
|---|
id | integer | Sí | Id del vehicle. |
Exemple
curl "https://el-teu-taller.example/api/v1/vehicles/1234" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Resposta
{
"id": 871,
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"plate": "1234 KLM",
"vin": "VSSZZZ5FZJR123456",
"brand": "Seat",
"model": "León",
"variant": "1.5 TSI",
"year": 2019,
"registration_date": "2019-03-15",
"fuel": "Gasolina",
"transmission": "Manual",
"engine_code": "DADA",
"horsepower": 130,
"displacement": "1498",
"color_code": null,
"environmental_label": "C",
"km": 84500,
"itv_expiry_date": "2027-03-15",
"status": "activo"
}
PATCH /api/v1/vehicles/{id} vehicles:write
Modificar un vehicle
Canvis parcials. client_id no admet null: un vehicle mai no es desvincula del titular per API (sí que pot passar a un altre client existent).
Permís necessari: vehicles:write.
Paràmetres
| Nom | Tipus | Obligatori | Descripció |
|---|
id | integer | Sí | Id del vehicle. |
Capçaleres
| Nom | Tipus | Obligatori | Descripció |
|---|
Idempotency-Key | string | No | Clau única per operació (es recomana un UUID). Repetir-la amb el mateix cos en 24 h retorna la resposta desada amb Idempotent-Replay: true; amb un altre cos, 409 idempotency_conflict. |
Cos
{
"client_id": 1204,
"plate": "1234 KLM",
"vin": "VSSZZZ5FZJR123456",
"brand": "Seat",
"model": "León",
"variant": "1.5 TSI",
"year": 2019,
"registration_date": "2019-03-15",
"fuel": "Gasolina",
"transmission": "Manual",
"engine_code": "DADA",
"horsepower": 130,
"displacement": "1498",
"color_code": null,
"environmental_label": "C",
"itv_expiry_date": "2027-03-15",
"status": "activo"
}
Exemple
curl -X PATCH "https://el-teu-taller.example/api/v1/vehicles/1234" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"client_id":1204,"plate":"1234 KLM","vin":"VSSZZZ5FZJR123456","brand":"Seat","model":"León","variant":"1.5 TSI","year":2019,"registration_date":"2019-03-15","fuel":"Gasolina","transmission":"Manual","engine_code":"DADA","horsepower":130,"displacement":"1498","color_code":null,"environmental_label":"C","itv_expiry_date":"2027-03-15","status":"activo"}'
Resposta
{
"id": 871,
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"plate": "1234 KLM",
"vin": "VSSZZZ5FZJR123456",
"brand": "Seat",
"model": "León",
"variant": "1.5 TSI",
"year": 2019,
"registration_date": "2019-03-15",
"fuel": "Gasolina",
"transmission": "Manual",
"engine_code": "DADA",
"horsepower": 130,
"displacement": "1498",
"color_code": null,
"environmental_label": "C",
"km": 84500,
"itv_expiry_date": "2027-03-15",
"status": "activo"
}
Pressupostos
GET /api/v1/budgets budgets:read
Llistar pressupostos
Mai no inclou els pressupostos d'ús intern del taller ni dades de cost. El detall (amb partides i totals) és a /budgets/{id}.
Permís necessari: budgets:read.
Consulta (query)
| Nom | Tipus | Obligatori | Descripció |
|---|
status | string | No | Estat exacte, amb el valor en castellà (Pendiente, Enviado, Aprobado, Finalizado, Facturado, Rechazado…). |
client_id | integer | No | Filtrar per client. |
vehicle_id | integer | No | Filtrar per vehicle. |
from | string (date-time) | No | Creats a partir d'aquesta data. |
to | string (date-time) | No | Creats fins a aquesta data. |
updated_since | string (date-time) | No | Només registres modificats a partir d'aquesta data (ISO 8601). |
limit | integer · default 50 | No | Resultats per pàgina (1–200). |
cursor | string | No | Cursor opac retornat a next_cursor de la pàgina anterior. |
Exemple
curl "https://el-teu-taller.example/api/v1/budgets" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Resposta
{
"data": [
{
"id": 1234,
"status": "Aprobado",
"created_at": "2026-10-06T09:30:00.000Z",
"updated_at": "2026-10-06T09:30:00.000Z",
"channel": "web",
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"vehicle_id": 871,
"vehicle": {
"id": 871,
"plate": "1234 KLM",
"brand": "Seat",
"model": "León"
},
"category": {
"id": 5,
"name": "Mantenimiento"
},
"subcategory": {
"id": 5,
"name": "Mantenimiento"
},
"assigned_user": {
"id": 3,
"name": "Marta"
},
"mechanic": {
"id": 3,
"name": "Marta"
},
"appointment": {
"start": "2026-10-06T09:30:00.000Z",
"end": "2026-10-06T10:30:00.000Z",
"status": "confirmed",
"client_confirmed_at": null,
"estimated_duration_minutes": 60,
"box": null
},
"date_in": null,
"date_out": null,
"km": 84500,
"client_reference": null,
"waiting_parts": false,
"on_hold": false,
"hold_until": null,
"client_signed_at": null,
"delivered_at": null,
"reject_reason": null,
"tracking_url": "https://taller.ejemplo.com/public/seguimiento?id=…"
}
],
"next_cursor": "aWQ6MTIzNA",
"has_more": true
}
POST /api/v1/budgets budgets:write
Crear un pressupost
Entra a «Pendiente» amb canal «API», igual que una alta des del programa (registre, fita d'obertura, webhook lead.created). Els totals es calculen al servidor amb l'impost del taller; si una partida no porta tax_rate, s'usa el del taller. El vehicle, si s'indica, ha de ser del client. No admet categories d'ús intern. Amb notify_client=true (i permís communications:send) s'envia al client l'acusament amb el seu enllaç de seguiment.
Permís necessari: budgets:write.
Capçaleres
| Nom | Tipus | Obligatori | Descripció |
|---|
Idempotency-Key | string | Sí | Clau única per operació (es recomana un UUID). Repetir-la amb el mateix cos en 24 h retorna la resposta desada amb Idempotent-Replay: true; amb un altre cos, 409 idempotency_conflict. |
Cos
{
"client_id": 1204,
"vehicle_id": 871,
"category_id": 5,
"subcategory_id": 51,
"client_reference": "PED-2026-118",
"public_notes": "Revisar també el soroll de la suspensió.",
"lines": [
{
"description": "Canvi d'oli i filtre",
"quantity": 1,
"unit_price": 65,
"tax_rate": 21,
"discount_pct": 0,
"line_type": "labor",
"reference": null,
"group_title": null
}
],
"notify_client": false
}
Exemple
curl -X POST "https://el-teu-taller.example/api/v1/budgets" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"client_id":1204,"vehicle_id":871,"category_id":5,"subcategory_id":51,"client_reference":"PED-2026-118","public_notes":"Revisar també el soroll de la suspensió.","lines":[{"description":"Canvi d'oli i filtre","quantity":1,"unit_price":65,"tax_rate":21,"discount_pct":0,"line_type":"labor","reference":null,"group_title":null}],"notify_client":false}'
Resposta
{
"id": 1234,
"status": "Aprobado",
"created_at": "2026-10-06T09:30:00.000Z",
"updated_at": "2026-10-06T09:30:00.000Z",
"channel": "web",
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"vehicle_id": 871,
"vehicle": {
"id": 871,
"plate": "1234 KLM",
"brand": "Seat",
"model": "León"
},
"category": {
"id": 5,
"name": "Mantenimiento"
},
"subcategory": {
"id": 5,
"name": "Mantenimiento"
},
"assigned_user": {
"id": 3,
"name": "Marta"
},
"mechanic": {
"id": 3,
"name": "Marta"
},
"appointment": {
"start": "2026-10-06T09:30:00.000Z",
"end": "2026-10-06T10:30:00.000Z",
"status": "confirmed",
"client_confirmed_at": null,
"estimated_duration_minutes": 60,
"box": {
"id": 2,
"name": "Elevador 2"
}
},
"date_in": null,
"date_out": null,
"km": 84500,
"client_reference": null,
"waiting_parts": false,
"on_hold": false,
"hold_until": null,
"client_signed_at": null,
"delivered_at": null,
"reject_reason": null,
"tracking_url": "https://taller.ejemplo.com/public/seguimiento?id=…",
"public_notes": "Revisar també el soroll a la suspensió.",
"totals": {
"base": 65,
"tax": 13.65,
"total": 78.65,
"currency": "EUR",
"tax_rates": [
{
"rate": 21,
"base": 65,
"quota": 13.65
}
]
},
"lines": [
{
"id": 5501,
"description": "Canvi d'oli i filtre",
"extended_detail": null,
"reference": null,
"line_type": "labor",
"group_title": null,
"quantity": 1,
"unit_price": 65,
"discount_pct": 0,
"tax_rate": 21,
"tax_exempt_code": null,
"price_estimated": false,
"base": 65,
"currency": "EUR",
"sort_order": 0
}
]
}
GET /api/v1/budgets/{id} budgets:read
Detall d'un pressupost
Partides (descripció, quantitat, preu unitari, impost, tipus, descompte), totals amb desglossament, cita, dates d'entrada i sortida, responsable i URL pública de seguiment.
Permís necessari: budgets:read.
Paràmetres
| Nom | Tipus | Obligatori | Descripció |
|---|
id | integer | Sí | Id del pressupost. |
Exemple
curl "https://el-teu-taller.example/api/v1/budgets/1234" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Resposta
{
"id": 1234,
"status": "Aprobado",
"created_at": "2026-10-06T09:30:00.000Z",
"updated_at": "2026-10-06T09:30:00.000Z",
"channel": "web",
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"vehicle_id": 871,
"vehicle": {
"id": 871,
"plate": "1234 KLM",
"brand": "Seat",
"model": "León"
},
"category": {
"id": 5,
"name": "Mantenimiento"
},
"subcategory": {
"id": 5,
"name": "Mantenimiento"
},
"assigned_user": {
"id": 3,
"name": "Marta"
},
"mechanic": {
"id": 3,
"name": "Marta"
},
"appointment": {
"start": "2026-10-06T09:30:00.000Z",
"end": "2026-10-06T10:30:00.000Z",
"status": "confirmed",
"client_confirmed_at": null,
"estimated_duration_minutes": 60,
"box": {
"id": 2,
"name": "Elevador 2"
}
},
"date_in": null,
"date_out": null,
"km": 84500,
"client_reference": null,
"waiting_parts": false,
"on_hold": false,
"hold_until": null,
"client_signed_at": null,
"delivered_at": null,
"reject_reason": null,
"tracking_url": "https://taller.ejemplo.com/public/seguimiento?id=…",
"public_notes": "Revisar també el soroll a la suspensió.",
"totals": {
"base": 65,
"tax": 13.65,
"total": 78.65,
"currency": "EUR",
"tax_rates": [
{
"rate": 21,
"base": 65,
"quota": 13.65
}
]
},
"lines": [
{
"id": 5501,
"description": "Canvi d'oli i filtre",
"extended_detail": null,
"reference": null,
"line_type": "labor",
"group_title": null,
"quantity": 1,
"unit_price": 65,
"discount_pct": 0,
"tax_rate": 21,
"tax_exempt_code": null,
"price_estimated": false,
"base": 65,
"currency": "EUR",
"sort_order": 0
}
]
}
POST /api/v1/budgets/{id}/lines budgets:write
Afegir una partida
La resta de partides conserven el seu id. Deixa instantània prèvia i registre com qualsevol edició del programa. 409 budget_locked si el pressupost és Facturado, Facturado externamente, Cancelado, Rechazado, Desistido o ja té factura.
Permís necessari: budgets:write.
Paràmetres
| Nom | Tipus | Obligatori | Descripció |
|---|
id | integer | Sí | Id del pressupost. |
Capçaleres
| Nom | Tipus | Obligatori | Descripció |
|---|
Idempotency-Key | string | Sí | Clau única per operació (es recomana un UUID). Repetir-la amb el mateix cos en 24 h retorna la resposta desada amb Idempotent-Replay: true; amb un altre cos, 409 idempotency_conflict. |
Cos
{
"description": "Canvi d'oli i filtre",
"quantity": 1,
"unit_price": 65,
"tax_rate": 21,
"discount_pct": 0,
"line_type": "labor",
"reference": null,
"group_title": null
}
Exemple
curl -X POST "https://el-teu-taller.example/api/v1/budgets/1234/lines" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"description":"Canvi d'oli i filtre","quantity":1,"unit_price":65,"tax_rate":21,"discount_pct":0,"line_type":"labor","reference":null,"group_title":null}'
Resposta
{
"line": {
"id": 5501,
"description": "Canvi d'oli i filtre",
"extended_detail": null,
"reference": null,
"line_type": "labor",
"group_title": null,
"quantity": 1,
"unit_price": 65,
"discount_pct": 0,
"tax_rate": 21,
"tax_exempt_code": null,
"price_estimated": false,
"base": 65,
"currency": "EUR",
"sort_order": 0
},
"budget": {
"id": 1234,
"status": "Aprobado",
"created_at": "2026-10-06T09:30:00.000Z",
"updated_at": "2026-10-06T09:30:00.000Z",
"channel": "web",
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"vehicle_id": 871,
"vehicle": {
"id": 871,
"plate": "1234 KLM",
"brand": "Seat",
"model": "León"
},
"category": {
"id": 5,
"name": "Mantenimiento"
},
"subcategory": {
"id": 5,
"name": "Mantenimiento"
},
"assigned_user": {
"id": 3,
"name": "Marta"
},
"mechanic": {
"id": 3,
"name": "Marta"
},
"appointment": {
"start": "2026-10-06T09:30:00.000Z",
"end": "2026-10-06T10:30:00.000Z",
"status": "confirmed",
"client_confirmed_at": null,
"estimated_duration_minutes": 60,
"box": {
"id": null,
"name": null
}
},
"date_in": null,
"date_out": null,
"km": 84500,
"client_reference": null,
"waiting_parts": false,
"on_hold": false,
"hold_until": null,
"client_signed_at": null,
"delivered_at": null,
"reject_reason": null,
"tracking_url": "https://taller.ejemplo.com/public/seguimiento?id=…",
"public_notes": "Revisar també el soroll a la suspensió.",
"totals": {
"base": 65,
"tax": 13.65,
"total": 78.65,
"currency": "EUR",
"tax_rates": [
{
"rate": 21,
"base": 65,
"quota": 13.65
}
]
},
"lines": [
{
"id": 5501,
"description": "Canvi d'oli i filtre",
"extended_detail": null,
"reference": null,
"line_type": "labor",
"group_title": null,
"quantity": 1,
"unit_price": 65,
"discount_pct": 0,
"tax_rate": 21,
"tax_exempt_code": null,
"price_estimated": false,
"base": 65,
"currency": "EUR",
"sort_order": 0
}
]
}
}
PATCH /api/v1/budgets/{id}/lines/{lineId} budgets:write
Modificar una partida
Permís necessari: budgets:write.
Paràmetres
| Nom | Tipus | Obligatori | Descripció |
|---|
id | integer | Sí | Id del pressupost. |
lineId | integer | Sí | Id de la partida. |
Capçaleres
| Nom | Tipus | Obligatori | Descripció |
|---|
Idempotency-Key | string | No | Clau única per operació (es recomana un UUID). Repetir-la amb el mateix cos en 24 h retorna la resposta desada amb Idempotent-Replay: true; amb un altre cos, 409 idempotency_conflict. |
Cos
{
"description": "Canvi d'oli i filtre",
"quantity": 1,
"unit_price": 65,
"tax_rate": 21,
"discount_pct": 0,
"line_type": "labor",
"reference": null,
"group_title": null
}
Exemple
curl -X PATCH "https://el-teu-taller.example/api/v1/budgets/1234/lines/5501" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"description":"Canvi d'oli i filtre","quantity":1,"unit_price":65,"tax_rate":21,"discount_pct":0,"line_type":"labor","reference":null,"group_title":null}'
Resposta
{
"line": {
"id": 5501,
"description": "Canvi d'oli i filtre",
"extended_detail": null,
"reference": null,
"line_type": "labor",
"group_title": null,
"quantity": 1,
"unit_price": 65,
"discount_pct": 0,
"tax_rate": 21,
"tax_exempt_code": null,
"price_estimated": false,
"base": 65,
"currency": "EUR",
"sort_order": 0
},
"budget": {
"id": 1234,
"status": "Aprobado",
"created_at": "2026-10-06T09:30:00.000Z",
"updated_at": "2026-10-06T09:30:00.000Z",
"channel": "web",
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"vehicle_id": 871,
"vehicle": {
"id": 871,
"plate": "1234 KLM",
"brand": "Seat",
"model": "León"
},
"category": {
"id": 5,
"name": "Mantenimiento"
},
"subcategory": {
"id": 5,
"name": "Mantenimiento"
},
"assigned_user": {
"id": 3,
"name": "Marta"
},
"mechanic": {
"id": 3,
"name": "Marta"
},
"appointment": {
"start": "2026-10-06T09:30:00.000Z",
"end": "2026-10-06T10:30:00.000Z",
"status": "confirmed",
"client_confirmed_at": null,
"estimated_duration_minutes": 60,
"box": {
"id": null,
"name": null
}
},
"date_in": null,
"date_out": null,
"km": 84500,
"client_reference": null,
"waiting_parts": false,
"on_hold": false,
"hold_until": null,
"client_signed_at": null,
"delivered_at": null,
"reject_reason": null,
"tracking_url": "https://taller.ejemplo.com/public/seguimiento?id=…",
"public_notes": "Revisar també el soroll a la suspensió.",
"totals": {
"base": 65,
"tax": 13.65,
"total": 78.65,
"currency": "EUR",
"tax_rates": [
{
"rate": 21,
"base": 65,
"quota": 13.65
}
]
},
"lines": [
{
"id": 5501,
"description": "Canvi d'oli i filtre",
"extended_detail": null,
"reference": null,
"line_type": "labor",
"group_title": null,
"quantity": 1,
"unit_price": 65,
"discount_pct": 0,
"tax_rate": 21,
"tax_exempt_code": null,
"price_estimated": false,
"base": 65,
"currency": "EUR",
"sort_order": 0
}
]
}
}
DELETE /api/v1/budgets/{id}/lines/{lineId} budgets:write
Treure una partida
Retorna el pressupost amb els totals recalculats. La partida queda a la instantània prèvia de l'historial de versions.
Permís necessari: budgets:write.
Paràmetres
| Nom | Tipus | Obligatori | Descripció |
|---|
id | integer | Sí | Id del pressupost. |
lineId | integer | Sí | Id de la partida. |
Exemple
curl -X DELETE "https://el-teu-taller.example/api/v1/budgets/1234/lines/5501" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Resposta
{
"id": 1234,
"status": "Aprobado",
"created_at": "2026-10-06T09:30:00.000Z",
"updated_at": "2026-10-06T09:30:00.000Z",
"channel": "web",
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"vehicle_id": 871,
"vehicle": {
"id": 871,
"plate": "1234 KLM",
"brand": "Seat",
"model": "León"
},
"category": {
"id": 5,
"name": "Mantenimiento"
},
"subcategory": {
"id": 5,
"name": "Mantenimiento"
},
"assigned_user": {
"id": 3,
"name": "Marta"
},
"mechanic": {
"id": 3,
"name": "Marta"
},
"appointment": {
"start": "2026-10-06T09:30:00.000Z",
"end": "2026-10-06T10:30:00.000Z",
"status": "confirmed",
"client_confirmed_at": null,
"estimated_duration_minutes": 60,
"box": {
"id": 2,
"name": "Elevador 2"
}
},
"date_in": null,
"date_out": null,
"km": 84500,
"client_reference": null,
"waiting_parts": false,
"on_hold": false,
"hold_until": null,
"client_signed_at": null,
"delivered_at": null,
"reject_reason": null,
"tracking_url": "https://taller.ejemplo.com/public/seguimiento?id=…",
"public_notes": "Revisar també el soroll a la suspensió.",
"totals": {
"base": 65,
"tax": 13.65,
"total": 78.65,
"currency": "EUR",
"tax_rates": [
{
"rate": 21,
"base": 65,
"quota": 13.65
}
]
},
"lines": [
{
"id": 5501,
"description": "Canvi d'oli i filtre",
"extended_detail": null,
"reference": null,
"line_type": "labor",
"group_title": null,
"quantity": 1,
"unit_price": 65,
"discount_pct": 0,
"tax_rate": 21,
"tax_exempt_code": null,
"price_estimated": false,
"base": 65,
"currency": "EUR",
"sort_order": 0
}
]
}
POST /api/v1/budgets/{id}/status budgets:write
Canviar l'estat
Admet Pendiente/En cotización/Enviado (abans de l'acceptació), En curso (pressupost ja acceptat), Finalizado (des d'Aprobado, En curso o En espera) i Cancelado. «Aprobado» respon 403 client_acceptance_required amb la tracking_url: l'acceptació la signa el client. Facturar, rebutjar o desistir responen 403 status_transition_forbidden; des de Facturado o Cancelado, 409 budget_locked. «Enviado» exigeix a més communications:send i sent_via: registra que el TEU sistema ja l'ha enviat (no l'envia). Cap canvi no avisa el client excepte Finalizado amb notify_client=true i communications:send.
Permís necessari: budgets:write.
Paràmetres
| Nom | Tipus | Obligatori | Descripció |
|---|
id | integer | Sí | Id del pressupost. |
Capçaleres
| Nom | Tipus | Obligatori | Descripció |
|---|
Idempotency-Key | string | Sí | Clau única per operació (es recomana un UUID). Repetir-la amb el mateix cos en 24 h retorna la resposta desada amb Idempotent-Replay: true; amb un altre cos, 409 idempotency_conflict. |
Cos
{
"status": "En curso",
"sent_via": "email",
"notify_client": false
}
Exemple
curl -X POST "https://el-teu-taller.example/api/v1/budgets/1234/status" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"status":"En curso","sent_via":"email","notify_client":false}'
Resposta
{
"id": 1234,
"status": "Aprobado",
"created_at": "2026-10-06T09:30:00.000Z",
"updated_at": "2026-10-06T09:30:00.000Z",
"channel": "web",
"client_id": 1204,
"client": {
"id": 1204,
"name": "Laura Gómez"
},
"vehicle_id": 871,
"vehicle": {
"id": 871,
"plate": "1234 KLM",
"brand": "Seat",
"model": "León"
},
"category": {
"id": 5,
"name": "Mantenimiento"
},
"subcategory": {
"id": 5,
"name": "Mantenimiento"
},
"assigned_user": {
"id": 3,
"name": "Marta"
},
"mechanic": {
"id": 3,
"name": "Marta"
},
"appointment": {
"start": "2026-10-06T09:30:00.000Z",
"end": "2026-10-06T10:30:00.000Z",
"status": "confirmed",
"client_confirmed_at": null,
"estimated_duration_minutes": 60,
"box": {
"id": 2,
"name": "Elevador 2"
}
},
"date_in": null,
"date_out": null,
"km": 84500,
"client_reference": null,
"waiting_parts": false,
"on_hold": false,
"hold_until": null,
"client_signed_at": null,
"delivered_at": null,
"reject_reason": null,
"tracking_url": "https://taller.ejemplo.com/public/seguimiento?id=…",
"public_notes": "Revisar també el soroll a la suspensió.",
"totals": {
"base": 65,
"tax": 13.65,
"total": 78.65,
"currency": "EUR",
"tax_rates": [
{
"rate": 21,
"base": 65,
"quota": 13.65
}
]
},
"lines": [
{
"id": 5501,
"description": "Canvi d'oli i filtre",
"extended_detail": null,
"reference": null,
"line_type": "labor",
"group_title": null,
"quantity": 1,
"unit_price": 65,
"discount_pct": 0,
"tax_rate": 21,
"tax_exempt_code": null,
"price_estimated": false,
"base": 65,
"currency": "EUR",
"sort_order": 0
}
]
}
POST /api/v1/budgets/{id}/documents budgets:write
Adjuntar un document
multipart/form-data amb el camp «file» (JPEG, PNG, WebP o PDF, comprovat pel contingut; màxim 4 MB). Per defecte només el veu el taller; client_visible=true el mostra a l'enllaç de seguiment i mechanic_visible=true a l'app del mecànic. L'empremta d'idempotència inclou el fitxer.
Permís necessari: budgets:write.
Paràmetres
| Nom | Tipus | Obligatori | Descripció |
|---|
id | integer | Sí | Id del pressupost. |
Capçaleres
| Nom | Tipus | Obligatori | Descripció |
|---|
Idempotency-Key | string | Sí | Clau única per operació (es recomana un UUID). Repetir-la amb el mateix cos en 24 h retorna la resposta desada amb Idempotent-Replay: true; amb un altre cos, 409 idempotency_conflict. |
Cos (multipart/form-data)
| Nom | Tipus | Obligatori | Descripció |
|---|
file | string (binary) | Sí | Fichero |
client_visible | string [true, false] | No | |
mechanic_visible | string [true, false] | No | |
Exemple
curl -X POST "https://el-teu-taller.example/api/v1/budgets/1234/documents" \
-H "Authorization: Bearer pt_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Idempotency-Key: $(uuidgen)" \
-F "file=@fichero.pdf" \
-F "client_visible=false" \
-F "mechanic_visible=false"
Resposta
{
"id": 991,
"budget_id": 1234,
"filename": "parte-de-trabajo.pdf",
"content_type": "application/pdf",
"size": 182044,
"url": "https://…/leads/1234/api-parte-de-trabajo.pdf",
"client_visible": false,
"mechanic_visible": false,
"created_at": "2026-10-06T09:30:00.000Z"
}