Réservations
Services, plages libres et rendez-vous. Une réservation faite ici envoie les mêmes courriels que la page de réservation.
GET
/api/v1/services
Lister les services réservables
Fonctionne avec une clé publique
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
lang |
requête |
string | null |
Non |
en or fr; without it, Accept-Language. |
cursor |
requête |
string | null |
Non |
|
limit |
requête |
integer |
Non |
Defaults to the maximum: most businesses fit in one page. |
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"data": [
{
"id": 3,
"name": "Coupe",
"description": "Lavage, coupe et coiffage.",
"duration_min": 45,
"price": "45.00",
"currency": "CAD",
"staff": [
{
"id": 1,
"name": "Julie"
}
],
"image_url": null
}
],
"next_cursor": null
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/services" \
-H "Authorization: Bearer dmk_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
GET
/api/v1/availability
Heures libres d'un service pour une journée
Fonctionne avec une clé publique
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
service |
requête |
integer |
Oui |
Service id. |
date |
requête |
string |
Oui |
Local day, YYYY-MM-DD. |
staff |
requête |
integer | null |
Non |
Staff id; omit for anyone. |
location |
requête |
string | null |
Non |
Location id or slug (GET /locations); omit for the primary location. |
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"data": [
{
"start": "2026-09-21T09:00:00-03:00",
"end": "2026-09-21T09:45:00-03:00",
"staff_id": null
}
],
"timezone": "America/Moncton"
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/availability?service=7&date=2026-09-21" \
-H "Authorization: Bearer dmk_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
GET
/api/v1/locations
Lister les emplacements de l'entreprise
Fonctionne avec une clé publique
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 429 Rate limited
Exemple de réponse (200)
{
"data": [
{
"id": 2,
"name": "Downtown",
"slug": "downtown",
"address": "12 King St, Moncton NB",
"phone": "506 555 0100",
"timezone": "America/Moncton",
"primary": true
}
]
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/locations" \
-H "Authorization: Bearer dmk_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
POST
/api/v1/bookings
Prendre un rendez-vous
Fonctionne avec une clé publique
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
Idempotency-Key |
en-tête |
string |
Non |
Retry safely: the first 2xx response is kept 24 hours and replayed with Idempotent-Replayed: true. Same key with a different body: 422 idempotency_key_reused. |
Corps de la requête
| Nom | Type | Obligatoire | Description |
service |
integer |
Oui |
Service id. |
start |
string |
Oui |
A start from /availability (ISO 8601). |
name |
string |
Oui |
|
email |
string |
Oui |
|
phone |
string | null |
Non |
|
staff |
integer | null |
Non |
Staff id; omit for anyone. |
location |
integer | null |
Non |
Location id (GET /locations); omit for the primary location. |
notes |
string | null |
Non |
|
lang |
string | null |
Non |
en or fr; defaults to the business language. |
consent |
boolean | null |
Non |
Opt-in to news from the business. |
policy_accepted |
boolean | null |
Non |
Required when the service asks for a deposit or card. |
Exemple de corps
{
"service": 7,
"start": "2026-09-21T09:00:00-03:00",
"name": "Lea Roy",
"email": "lea@example.com",
"phone": "506 555 0100",
"staff": null,
"location": null,
"notes": "First visit",
"lang": "en",
"consent": false,
"policy_accepted": true
}
Réponses
- 201 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 404 Not found
- 409 Conflict
- 422 Validation error
- 429 Rate limited
Exemple de réponse (201)
{
"id": 1,
"status": "confirmed",
"start": "2026-10-09T09:00:00-03:00",
"end": "2026-10-09T09:45:00-03:00",
"service": {
"id": 3,
"name": "Coupe"
},
"staff": {
"id": 1,
"name": "Julie"
},
"location": {
"id": 2,
"name": "Salon Ana",
"timezone": "America/Moncton"
},
"customer": {
"name": "Marie Tremblay",
"email": "marie.tremblay@mail.test",
"phone": "506 555 0123"
},
"notes": "First visit",
"lang": "fr",
"source": "api",
"created_at": "2026-10-02T23:24:52-03:00",
"token": "IfnZPtmgcfpabtYFc_UU4AxdOWc1MHHGjdUU-jrbLAA",
"manage_url": "https://demarkstudio.ca/citas/IfnZPtmgcfpabtYFc_UU4AxdOWc1MHHGjdUU-jrbLAA",
"cancel_url": "https://demarkstudio.ca/citas/IfnZPtmgcfpabtYFc_UU4AxdOWc1MHHGjdUU-jrbLAA/cancel",
"payment_url": null
}
Essayez avec curl
curl -X POST "https://demarkstudio.ca/api/v1/bookings" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"service": 7, "start": "2026-09-21T09:00:00-03:00", "name": "Lea Roy", "email": "lea@example.com", "phone": "506 555 0100", "staff": null, "location": null, "notes": "First visit", "lang": "en", "consent": false, "policy_accepted": true}'
Retour à l'index
GET
/api/v1/bookings
Lister les réservations
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
from |
requête |
string | null |
Non |
Start day or datetime (ISO). |
to |
requête |
string | null |
Non |
End day (exclusive) or datetime (ISO). |
status |
requête |
string | null |
Non |
pending, confirmed, cancelled, completed or no_show. |
location |
requête |
integer | null |
Non |
Only this location's bookings (GET /locations). |
cursor |
requête |
string | null |
Non |
|
limit |
requête |
integer |
Non |
|
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"data": [
{
"id": 1,
"status": "confirmed",
"start": "2026-10-09T09:00:00-03:00",
"end": "2026-10-09T09:45:00-03:00",
"service": {
"id": 3,
"name": "Coupe"
},
"staff": {
"id": 1,
"name": "Julie"
},
"location": {
"id": 2,
"name": "Salon Ana",
"timezone": "America/Moncton"
},
"customer": {
"name": "Marie Tremblay",
"email": "marie.tremblay@mail.test",
"phone": "506 555 0123"
},
"notes": "First visit",
"lang": "fr",
"source": "api",
"created_at": "2026-10-02T23:24:52-03:00"
}
],
"next_cursor": "MTAx"
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/bookings" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
GET
/api/v1/bookings/{booking_id}
Lire une réservation
Fonctionne avec une clé publique
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
booking_id |
chemin |
integer |
Oui |
|
token |
requête |
string | null |
Non |
Management token. Required with a public key or without a key. |
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 1,
"status": "confirmed",
"start": "2026-10-09T09:00:00-03:00",
"end": "2026-10-09T09:45:00-03:00",
"service": {
"id": 3,
"name": "Coupe"
},
"staff": {
"id": 1,
"name": "Julie"
},
"location": {
"id": 2,
"name": "Salon Ana",
"timezone": "America/Moncton"
},
"customer": {
"name": "Marie Tremblay",
"email": "marie.tremblay@mail.test",
"phone": "506 555 0123"
},
"notes": "First visit",
"lang": "fr",
"source": "api",
"created_at": "2026-10-02T23:24:52-03:00"
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/bookings/1" \
-H "Authorization: Bearer dmk_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
DELETE
/api/v1/bookings/{booking_id}
Annuler une réservation
Fonctionne avec une clé publique
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
booking_id |
chemin |
integer |
Oui |
|
token |
requête |
string | null |
Non |
Management token. Required with a public key or without a key. |
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 404 Not found
- 409 Conflict
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 101,
"status": "cancelled"
}
Essayez avec curl
curl -X DELETE "https://demarkstudio.ca/api/v1/bookings/1" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
PATCH
/api/v1/bookings/{booking_id}
Reprogrammer une réservation ou modifier ses notes
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
booking_id |
chemin |
integer |
Oui |
|
Corps de la requête
| Nom | Type | Obligatoire | Description |
start |
string | null |
Non |
New start (ISO 8601), from GET /availability/slots. Reschedules the booking: this id is cancelled and a new one is created (see the returned id). Omit to only update notes. |
notes |
string | null |
Non |
|
location |
integer | null |
Non |
Move the booking to this location (GET /locations). Works like a reschedule: with start, at that time; without it, at the same time. The staff member must work there, the service's room must be one of that location's, and the time must be free there (a staff member's bookings at every location count). |
Exemple de corps
{
"start": "2026-09-21T09:00:00-03:00",
"notes": "Client asked to move to the morning",
"location": null
}
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 404 Not found
- 409 Conflict
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 101,
"status": "confirmed",
"start": "2026-09-21T09:00:00-03:00",
"end": "2026-09-21T09:45:00-03:00",
"service": {
"id": 7,
"name": "Haircut"
},
"staff": {
"id": 3,
"name": "Julie"
},
"location": {
"id": 2,
"name": "Downtown",
"timezone": "America/Moncton"
},
"customer": {
"name": "Lea Roy",
"email": "lea@example.com",
"phone": ""
},
"notes": "First visit",
"lang": "en",
"source": "api",
"created_at": "2026-09-14T10:02:11-03:00",
"manage_url": "https://demarkstudio.ca/citas/kR3...x9"
}
Essayez avec curl
curl -X PATCH "https://demarkstudio.ca/api/v1/bookings/1" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"start": "2026-09-21T09:00:00-03:00", "notes": "Client asked to move to the morning", "location": null}'
Retour à l'index
GET
/api/v1/availability/slots
Heures libres sur une plage de dates
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
service_id |
requête |
integer |
Oui |
|
from |
requête |
string |
Oui |
First local day, YYYY-MM-DD. |
to |
requête |
string |
Oui |
Last local day, YYYY-MM-DD (inclusive). |
staff_id |
requête |
integer | null |
Non |
|
location |
requête |
string | null |
Non |
Location id or slug (GET /locations); omit for the primary location. |
Réponses
- 200 Successful Response
- 400 Bad request
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"data": [
{
"start": "2026-09-21T09:00:00-03:00",
"end": "2026-09-21T09:45:00-03:00",
"staff_id": null
}
],
"timezone": "America/Moncton"
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/availability/slots?service_id=1&from=2026-09-21&to=2026-09-25" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
POST
/api/v1/booking-series
Créer une série de réservations récurrentes
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
Idempotency-Key |
en-tête |
string |
Non |
Retry safely: the first 2xx response is kept 24 hours and replayed with Idempotent-Replayed: true. Same key with a different body: 422 idempotency_key_reused. |
Corps de la requête
| Nom | Type | Obligatoire | Description |
service |
integer |
Oui |
Service id. |
start |
string |
Oui |
First booking (ISO 8601). Every date keeps this local time. |
name |
string |
Oui |
|
email |
string |
Non |
|
phone |
string | null |
Non |
|
staff |
integer | null |
Non |
Staff id; omit to leave it unassigned. |
location |
integer | null |
Non |
Location id (GET /locations); omit for the primary location. |
notes |
string | null |
Non |
|
lang |
string | null |
Non |
en or fr; defaults to the business language. |
notify |
boolean |
Non |
Email the customer one message with every date. |
recurrence |
Recurrencia |
Oui |
|
Exemple de corps
{
"service": 7,
"start": "2026-10-06T10:00:00-03:00",
"name": "Lea Roy",
"email": "lea@example.com",
"phone": "506 555 0100",
"staff": null,
"location": null,
"notes": "Physio, every two weeks",
"lang": "en",
"notify": true,
"recurrence": {
"frequency": "every_2_weeks",
"count": 6,
"until": null,
"skip_conflicts": true
}
}
Réponses
- 201 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 404 Not found
- 409 Conflict
- 422 Validation error
- 429 Rate limited
Exemple de réponse (201)
{
"id": 12,
"frequency": "every_2_weeks",
"count": 6,
"until": null,
"created_at": "2026-10-02T09:12:00-03:00",
"bookings": [
{
"id": 1,
"status": "confirmed",
"start": "2026-10-09T09:00:00-03:00",
"end": "2026-10-09T09:45:00-03:00",
"service": {
"id": 3,
"name": "Coupe"
},
"staff": {
"id": 1,
"name": "Julie"
},
"location": {
"id": 2,
"name": "Salon Ana",
"timezone": "America/Moncton"
},
"customer": {
"name": "Marie Tremblay",
"email": "marie.tremblay@mail.test",
"phone": "506 555 0123"
},
"notes": "First visit",
"lang": "fr",
"source": "api",
"created_at": "2026-10-02T23:24:52-03:00"
}
],
"skipped": [
{
"start": "2026-10-20T10:00:00-03:00",
"reasons": [
"staff_busy"
]
}
]
}
Essayez avec curl
curl -X POST "https://demarkstudio.ca/api/v1/booking-series" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"service": 7, "start": "2026-10-06T10:00:00-03:00", "name": "Lea Roy", "email": "lea@example.com", "phone": "506 555 0100", "staff": null, "location": null, "notes": "Physio, every two weeks", "lang": "en", "notify": true, "recurrence": {"frequency": "every_2_weeks", "count": 6, "until": null, "skip_conflicts": true}}'
Retour à l'index
GET
/api/v1/booking-series/{series_id}
Lire une série récurrente
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
series_id |
chemin |
integer |
Oui |
|
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 12,
"frequency": "every_2_weeks",
"count": 6,
"until": null,
"created_at": "2026-10-02T09:12:00-03:00",
"bookings": [
{
"id": 1,
"status": "confirmed",
"start": "2026-10-09T09:00:00-03:00",
"end": "2026-10-09T09:45:00-03:00",
"service": {
"id": 3,
"name": "Coupe"
},
"staff": {
"id": 1,
"name": "Julie"
},
"location": {
"id": 2,
"name": "Salon Ana",
"timezone": "America/Moncton"
},
"customer": {
"name": "Marie Tremblay",
"email": "marie.tremblay@mail.test",
"phone": "506 555 0123"
},
"notes": "First visit",
"lang": "fr",
"source": "api",
"created_at": "2026-10-02T23:24:52-03:00"
}
],
"skipped": [
{
"start": "2026-10-20T10:00:00-03:00",
"reasons": [
"staff_busy"
]
}
]
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/booking-series/1" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
POST
/api/v1/booking-series/{series_id}/cancel
Annuler une série, ou une réservation et les suivantes
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
series_id |
chemin |
integer |
Oui |
|
Corps de la requête
| Nom | Type | Obligatoire | Description |
from_booking |
integer | null |
Non |
Cancel this booking and the following ones. Omit to cancel every booking of the series that has not started yet. |
notify |
boolean |
Non |
Email the customer one message with the cancelled dates. |
Exemple de corps
{
"from_booking": null,
"notify": true
}
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 12,
"cancelled": [
41,
42,
43
]
}
Essayez avec curl
curl -X POST "https://demarkstudio.ca/api/v1/booking-series/1/cancel" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"from_booking": null, "notify": true}'
Retour à l'index
Clients
La liste de clients de l'entreprise. Clé secrète seulement.
GET
/api/v1/customers
Lister ou chercher des clients
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
email |
requête |
string | null |
Non |
Exact email. |
q |
requête |
string | null |
Non |
Search in name, email, company, phone. |
cursor |
requête |
string | null |
Non |
|
limit |
requête |
integer |
Non |
|
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"data": [
{
"id": 2,
"name": "Marie Tremblay",
"email": "marie.tremblay@mail.test",
"phone": "506 555 0123",
"company": "",
"lang": "fr",
"notes": "Prefers mornings",
"marketing_consent": false,
"created_at": "2026-10-02T23:24:52-03:00"
}
],
"next_cursor": null
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/customers" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
POST
/api/v1/customers
Ajouter un client
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
Idempotency-Key |
en-tête |
string |
Non |
Retry safely: the first 2xx response is kept 24 hours and replayed with Idempotent-Replayed: true. Same key with a different body: 422 idempotency_key_reused. |
Corps de la requête
| Nom | Type | Obligatoire | Description |
name |
string |
Oui |
|
email |
string |
Oui |
|
phone |
string | null |
Non |
|
lang |
string | null |
Non |
|
consent |
boolean |
Oui |
Must be true: the customer agreed to be stored. |
notes |
string | null |
Non |
|
Exemple de corps
{
"name": "Lea Roy",
"email": "lea@example.com",
"phone": "506 555 0100",
"lang": "fr",
"consent": true,
"notes": "Met at the fair"
}
Réponses
- 200 Already existed
- 201 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 31,
"name": "Lea Roy",
"email": "lea@example.com",
"phone": "506 555 0100",
"company": "",
"lang": "fr",
"notes": "",
"marketing_consent": false,
"created_at": "2026-09-14T10:02:11-03:00",
"created": true
}
Exemple de réponse (201)
{
"id": 31,
"name": "Lea Roy",
"email": "lea@example.com",
"phone": "506 555 0100",
"company": "",
"lang": "fr",
"notes": "",
"marketing_consent": false,
"created_at": "2026-09-14T10:02:11-03:00",
"created": true
}
Essayez avec curl
curl -X POST "https://demarkstudio.ca/api/v1/customers" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"name": "Lea Roy", "email": "lea@example.com", "phone": "506 555 0100", "lang": "fr", "consent": true, "notes": "Met at the fair"}'
Retour à l'index
GET
/api/v1/customers/{customer_id}
Lire un client
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
customer_id |
chemin |
integer |
Oui |
|
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 2,
"name": "Marie Tremblay",
"email": "marie.tremblay@mail.test",
"phone": "506 555 0123",
"company": "",
"lang": "fr",
"notes": "Prefers mornings",
"marketing_consent": false,
"created_at": "2026-10-02T23:24:52-03:00"
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/customers/1" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
PATCH
/api/v1/customers/{customer_id}
Modifier un client
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
customer_id |
chemin |
integer |
Oui |
|
Corps de la requête
| Nom | Type | Obligatoire | Description |
name |
string | null |
Non |
|
email |
string | null |
Non |
422 if empty; 409 if another customer of this business already has it. |
phone |
string | null |
Non |
|
lang |
string | null |
Non |
en or fr. |
notes |
string | null |
Non |
|
Exemple de corps
{
"name": "string",
"email": "string",
"phone": "string",
"lang": "string",
"notes": "string"
}
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 404 Not found
- 409 Conflict
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 2,
"name": "Marie Tremblay",
"email": "marie.tremblay@mail.test",
"phone": "506 555 0123",
"company": "",
"lang": "fr",
"notes": "Prefers mornings",
"marketing_consent": false,
"created_at": "2026-10-02T23:24:52-03:00"
}
Essayez avec curl
curl -X PATCH "https://demarkstudio.ca/api/v1/customers/1" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"name": "string", "email": "string", "phone": "string", "lang": "string", "notes": "string"}'
Retour à l'index
Products
The shop catalogue: products, options, variants and stock.
POST
/api/v1/products
Créer un produit
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
Idempotency-Key |
en-tête |
string |
Non |
Retry safely: the first 2xx response is kept 24 hours and replayed with Idempotent-Replayed: true. Same key with a different body: 422 idempotency_key_reused. |
Corps de la requête
| Nom | Type | Obligatoire | Description |
name_en |
string |
Oui |
|
name_fr |
string | null |
Non |
|
description_en |
string | null |
Non |
|
description_fr |
string | null |
Non |
|
price_cents |
integer |
Oui |
Base price in cents, in the business currency. |
type |
string |
Non |
|
stock |
integer | null |
Non |
null = unlimited. |
public |
boolean |
Non |
false keeps it as a draft: POST /products/{id}/publish shows it. |
option_groups |
array[OptionGroupInput] |
Non |
|
variants |
array[VariantInput] |
Non |
Settings for some combinations; the others are calculated. |
Exemple de corps
{
"name_en": "Bird's eye vinyl",
"name_fr": "Vinyle oeil d'oiseau",
"description_en": "Wall panel.",
"description_fr": "Panneau mural.",
"price_cents": 2000,
"type": "physical",
"stock": 10,
"public": false,
"option_groups": [
{
"id": "colour",
"name_en": "Colour",
"name_fr": "Couleur",
"mode": "surcharge",
"options": [
null
]
}
],
"variants": [
{
"options": {
"colour": "honey",
"size": "12x12"
},
"sku": "BE-HON-12",
"price_cents": null,
"stock": 4,
"active": true
}
]
}
Réponses
- 201 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 409 Conflict
- 422 Validation error
- 429 Rate limited
Exemple de réponse (201)
{
"id": 9,
"slug": "birds-eye-vinyl",
"name": "Bird's eye vinyl",
"name_en": "Bird's eye vinyl",
"name_fr": "Vinyle oeil d'oiseau",
"description": "Wall panel.",
"description_en": "Wall panel.",
"description_fr": "Panneau mural.",
"type": "physical",
"price_cents": 2000,
"currency": "CAD",
"stock": 10,
"public": true,
"sold_out": false,
"url": "https://demarkstudio.ca/salon-ana/shop/birds-eye-vinyl",
"images": [
{
"id": 41,
"url": "https://demarkstudio.ca/m/12/41.webp",
"thumbnail_url": "https://demarkstudio.ca/m/12/41_t.webp",
"alt": ""
}
],
"option_groups": [
{
"id": "colour",
"name": "Colour",
"name_en": "Colour",
"name_fr": "Couleur",
"mode": "surcharge",
"options": [
null
]
}
],
"variants": [
{
"id": "honey|12x12",
"sku": "BE-HON-12",
"price_cents": 1500,
"stock": 4,
"shared_stock": false,
"options": {
"colour": "honey",
"size": "12x12"
},
"active": true,
"available": true
}
],
"policies": {
"lang": "en",
"shipping": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
},
"returns": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
}
},
"created_at": "2026-09-14T10:02:11-03:00",
"updated_at": "2026-09-14T10:02:11-03:00"
}
Essayez avec curl
curl -X POST "https://demarkstudio.ca/api/v1/products" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"name_en": "Bird's eye vinyl", "name_fr": "Vinyle oeil d'oiseau", "description_en": "Wall panel.", "description_fr": "Panneau mural.", "price_cents": 2000, "type": "physical", "stock": 10, "public": false, "option_groups": [{"id": "colour", "name_en": "Colour", "name_fr": "Couleur", "mode": "surcharge", "options": [null]}], "variants": [{"options": {"colour": "honey", "size": "12x12"}, "sku": "BE-HON-12", "price_cents": null, "stock": 4, "active": true}]}'
Retour à l'index
GET
/api/v1/products/{product_id}
Lire un produit avec ses options et ses variantes
Fonctionne avec une clé publique
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
product_id |
chemin |
integer |
Oui |
Product id. |
lang |
requête |
string | null |
Non |
en or fr; without it, Accept-Language. |
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 9,
"slug": "birds-eye-vinyl",
"name": "Bird's eye vinyl",
"name_en": "Bird's eye vinyl",
"name_fr": "Vinyle oeil d'oiseau",
"description": "Wall panel.",
"description_en": "Wall panel.",
"description_fr": "Panneau mural.",
"type": "physical",
"price_cents": 2000,
"currency": "CAD",
"stock": 10,
"public": true,
"sold_out": false,
"url": "https://demarkstudio.ca/salon-ana/shop/birds-eye-vinyl",
"images": [
{
"id": 41,
"url": "https://demarkstudio.ca/m/12/41.webp",
"thumbnail_url": "https://demarkstudio.ca/m/12/41_t.webp",
"alt": ""
}
],
"option_groups": [
{
"id": "colour",
"name": "Colour",
"name_en": "Colour",
"name_fr": "Couleur",
"mode": "surcharge",
"options": [
null
]
}
],
"variants": [
{
"id": "honey|12x12",
"sku": "BE-HON-12",
"price_cents": 1500,
"stock": 4,
"shared_stock": false,
"options": {
"colour": "honey",
"size": "12x12"
},
"active": true,
"available": true
}
],
"policies": {
"lang": "en",
"shipping": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
},
"returns": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
}
},
"created_at": "2026-09-14T10:02:11-03:00",
"updated_at": "2026-09-14T10:02:11-03:00"
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/products/1" \
-H "Authorization: Bearer dmk_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
PATCH
/api/v1/products/{product_id}
Modifier un produit
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
product_id |
chemin |
integer |
Oui |
Product id. |
Corps de la requête
| Nom | Type | Obligatoire | Description |
name_en |
string | null |
Non |
|
name_fr |
string | null |
Non |
|
description_en |
string | null |
Non |
|
description_fr |
string | null |
Non |
|
price_cents |
integer | null |
Non |
|
public |
boolean | null |
Non |
|
stock |
integer | null |
Non |
Absolute product stock; null = unlimited. Not together with stock_delta. |
stock_delta |
integer | null |
Non |
Refused with 422 insufficient_stock if it would go below 0. |
Exemple de corps
{
"name_en": "Walnut vinyl",
"name_fr": null,
"description_en": null,
"description_fr": null,
"price_cents": 2200,
"public": true,
"stock": null,
"stock_delta": 5
}
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 9,
"slug": "birds-eye-vinyl",
"name": "Bird's eye vinyl",
"name_en": "Bird's eye vinyl",
"name_fr": "Vinyle oeil d'oiseau",
"description": "Wall panel.",
"description_en": "Wall panel.",
"description_fr": "Panneau mural.",
"type": "physical",
"price_cents": 2000,
"currency": "CAD",
"stock": 10,
"public": true,
"sold_out": false,
"url": "https://demarkstudio.ca/salon-ana/shop/birds-eye-vinyl",
"images": [
{
"id": 41,
"url": "https://demarkstudio.ca/m/12/41.webp",
"thumbnail_url": "https://demarkstudio.ca/m/12/41_t.webp",
"alt": ""
}
],
"option_groups": [
{
"id": "colour",
"name": "Colour",
"name_en": "Colour",
"name_fr": "Couleur",
"mode": "surcharge",
"options": [
null
]
}
],
"variants": [
{
"id": "honey|12x12",
"sku": "BE-HON-12",
"price_cents": 1500,
"stock": 4,
"shared_stock": false,
"options": {
"colour": "honey",
"size": "12x12"
},
"active": true,
"available": true
}
],
"policies": {
"lang": "en",
"shipping": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
},
"returns": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
}
},
"created_at": "2026-09-14T10:02:11-03:00",
"updated_at": "2026-09-14T10:02:11-03:00"
}
Essayez avec curl
curl -X PATCH "https://demarkstudio.ca/api/v1/products/1" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"name_en": "Walnut vinyl", "name_fr": null, "description_en": null, "description_fr": null, "price_cents": 2200, "public": true, "stock": null, "stock_delta": 5}'
Retour à l'index
POST
/api/v1/products/{product_id}/publish
Publier un produit dans la boutique
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
product_id |
chemin |
integer |
Oui |
Product id. |
Idempotency-Key |
en-tête |
string |
Non |
Retry safely: the first 2xx response is kept 24 hours and replayed with Idempotent-Replayed: true. Same key with a different body: 422 idempotency_key_reused. |
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 409 Conflict
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 9,
"slug": "birds-eye-vinyl",
"name": "Bird's eye vinyl",
"name_en": "Bird's eye vinyl",
"name_fr": "Vinyle oeil d'oiseau",
"description": "Wall panel.",
"description_en": "Wall panel.",
"description_fr": "Panneau mural.",
"type": "physical",
"price_cents": 2000,
"currency": "CAD",
"stock": 10,
"public": true,
"sold_out": false,
"url": "https://demarkstudio.ca/salon-ana/shop/birds-eye-vinyl",
"images": [
{
"id": 41,
"url": "https://demarkstudio.ca/m/12/41.webp",
"thumbnail_url": "https://demarkstudio.ca/m/12/41_t.webp",
"alt": ""
}
],
"option_groups": [
{
"id": "colour",
"name": "Colour",
"name_en": "Colour",
"name_fr": "Couleur",
"mode": "surcharge",
"options": [
null
]
}
],
"variants": [
{
"id": "honey|12x12",
"sku": "BE-HON-12",
"price_cents": 1500,
"stock": 4,
"shared_stock": false,
"options": {
"colour": "honey",
"size": "12x12"
},
"active": true,
"available": true
}
],
"policies": {
"lang": "en",
"shipping": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
},
"returns": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
}
},
"created_at": "2026-09-14T10:02:11-03:00",
"updated_at": "2026-09-14T10:02:11-03:00"
}
Essayez avec curl
curl -X POST "https://demarkstudio.ca/api/v1/products/1/publish" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
POST
/api/v1/products/{product_id}/unpublish
Retirer un produit de la boutique
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
product_id |
chemin |
integer |
Oui |
Product id. |
Idempotency-Key |
en-tête |
string |
Non |
Retry safely: the first 2xx response is kept 24 hours and replayed with Idempotent-Replayed: true. Same key with a different body: 422 idempotency_key_reused. |
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 409 Conflict
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 9,
"slug": "birds-eye-vinyl",
"name": "Bird's eye vinyl",
"name_en": "Bird's eye vinyl",
"name_fr": "Vinyle oeil d'oiseau",
"description": "Wall panel.",
"description_en": "Wall panel.",
"description_fr": "Panneau mural.",
"type": "physical",
"price_cents": 2000,
"currency": "CAD",
"stock": 10,
"public": true,
"sold_out": false,
"url": "https://demarkstudio.ca/salon-ana/shop/birds-eye-vinyl",
"images": [
{
"id": 41,
"url": "https://demarkstudio.ca/m/12/41.webp",
"thumbnail_url": "https://demarkstudio.ca/m/12/41_t.webp",
"alt": ""
}
],
"option_groups": [
{
"id": "colour",
"name": "Colour",
"name_en": "Colour",
"name_fr": "Couleur",
"mode": "surcharge",
"options": [
null
]
}
],
"variants": [
{
"id": "honey|12x12",
"sku": "BE-HON-12",
"price_cents": 1500,
"stock": 4,
"shared_stock": false,
"options": {
"colour": "honey",
"size": "12x12"
},
"active": true,
"available": true
}
],
"policies": {
"lang": "en",
"shipping": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
},
"returns": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
}
},
"created_at": "2026-09-14T10:02:11-03:00",
"updated_at": "2026-09-14T10:02:11-03:00"
}
Essayez avec curl
curl -X POST "https://demarkstudio.ca/api/v1/products/1/unpublish" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
POST
/api/v1/products/{product_id}/option-groups
Ajouter un groupe d'options à un produit
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
product_id |
chemin |
integer |
Oui |
Product id. |
Idempotency-Key |
en-tête |
string |
Non |
Retry safely: the first 2xx response is kept 24 hours and replayed with Idempotent-Replayed: true. Same key with a different body: 422 idempotency_key_reused. |
Corps de la requête
| Nom | Type | Obligatoire | Description |
id |
string | null |
Non |
Group id (slug). Omit it to derive it from name_en. |
name_en |
string |
Oui |
|
name_fr |
string | null |
Non |
Defaults to name_en. |
mode |
string |
Non |
surcharge adds amount_cents; price sets the price. At most one price group per product. |
options |
array[OptionInput] |
Oui |
|
Exemple de corps
{
"id": "colour",
"name_en": "Colour",
"name_fr": "Couleur",
"mode": "surcharge",
"options": [
{
"id": "honey",
"name_en": "Honey maple",
"name_fr": "Erable miel",
"amount_cents": 300,
"image_id": null
}
]
}
Réponses
- 201 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 409 Conflict
- 422 Validation error
- 429 Rate limited
Exemple de réponse (201)
{
"id": "colour",
"name": "Colour",
"name_en": "Colour",
"name_fr": "Couleur",
"mode": "surcharge",
"options": [
{
"id": "honey",
"name": "Honey maple",
"name_en": "Honey maple",
"name_fr": "Erable miel",
"amount_cents": null,
"image_id": null,
"image_url": null
}
]
}
Essayez avec curl
curl -X POST "https://demarkstudio.ca/api/v1/products/1/option-groups" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"id": "colour", "name_en": "Colour", "name_fr": "Couleur", "mode": "surcharge", "options": [{"id": "honey", "name_en": "Honey maple", "name_fr": "Erable miel", "amount_cents": 300, "image_id": null}]}'
Retour à l'index
PATCH
/api/v1/products/{product_id}/option-groups/{group_id}
Modifier un groupe d'options
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
product_id |
chemin |
integer |
Oui |
Product id. |
group_id |
chemin |
string |
Oui |
Option group id. |
Corps de la requête
| Nom | Type | Obligatoire | Description |
name_en |
string | null |
Non |
|
name_fr |
string | null |
Non |
|
mode |
string | null |
Non |
|
options |
array[OptionInput] | null |
Non |
Replaces the whole list. Variants of option ids that disappear are dropped; the others keep sku, price and stock. |
Exemple de corps
{
"name_en": "Finish",
"name_fr": "Fini",
"mode": "price",
"options": [
{
"id": "honey",
"name_en": "Honey maple",
"name_fr": "Erable miel",
"amount_cents": 300,
"image_id": null
}
]
}
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": "colour",
"name": "Colour",
"name_en": "Colour",
"name_fr": "Couleur",
"mode": "surcharge",
"options": [
{
"id": "honey",
"name": "Honey maple",
"name_en": "Honey maple",
"name_fr": "Erable miel",
"amount_cents": null,
"image_id": null,
"image_url": null
}
]
}
Essayez avec curl
curl -X PATCH "https://demarkstudio.ca/api/v1/products/1/option-groups/string" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"name_en": "Finish", "name_fr": "Fini", "mode": "price", "options": [{"id": "honey", "name_en": "Honey maple", "name_fr": "Erable miel", "amount_cents": 300, "image_id": null}]}'
Retour à l'index
DELETE
/api/v1/products/{product_id}/option-groups/{group_id}
Supprimer un groupe d'options
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
product_id |
chemin |
integer |
Oui |
Product id. |
group_id |
chemin |
string |
Oui |
Option group id. |
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 9,
"slug": "birds-eye-vinyl",
"name": "Bird's eye vinyl",
"name_en": "Bird's eye vinyl",
"name_fr": "Vinyle oeil d'oiseau",
"description": "Wall panel.",
"description_en": "Wall panel.",
"description_fr": "Panneau mural.",
"type": "physical",
"price_cents": 2000,
"currency": "CAD",
"stock": 10,
"public": true,
"sold_out": false,
"url": "https://demarkstudio.ca/salon-ana/shop/birds-eye-vinyl",
"images": [
{
"id": 41,
"url": "https://demarkstudio.ca/m/12/41.webp",
"thumbnail_url": "https://demarkstudio.ca/m/12/41_t.webp",
"alt": ""
}
],
"option_groups": [
{
"id": "colour",
"name": "Colour",
"name_en": "Colour",
"name_fr": "Couleur",
"mode": "surcharge",
"options": [
null
]
}
],
"variants": [
{
"id": "honey|12x12",
"sku": "BE-HON-12",
"price_cents": 1500,
"stock": 4,
"shared_stock": false,
"options": {
"colour": "honey",
"size": "12x12"
},
"active": true,
"available": true
}
],
"policies": {
"lang": "en",
"shipping": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
},
"returns": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
}
},
"created_at": "2026-09-14T10:02:11-03:00",
"updated_at": "2026-09-14T10:02:11-03:00"
}
Essayez avec curl
curl -X DELETE "https://demarkstudio.ca/api/v1/products/1/option-groups/string" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
POST
/api/v1/products/{product_id}/variants
Configurer une variante
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
product_id |
chemin |
integer |
Oui |
Product id. |
Idempotency-Key |
en-tête |
string |
Non |
Retry safely: the first 2xx response is kept 24 hours and replayed with Idempotent-Replayed: true. Same key with a different body: 422 idempotency_key_reused. |
Corps de la requête
| Nom | Type | Obligatoire | Description |
options |
object |
Oui |
One option per group: {group id: option id}. |
sku |
string | null |
Non |
|
price_cents |
integer | null |
Non |
Fixed price; null = calculated from the product price and the option amounts. |
stock |
integer | null |
Non |
Own stock; null = shares the product stock. |
active |
boolean |
Non |
An inactive variant is kept but cannot be bought. |
Exemple de corps
{
"options": {
"colour": "honey",
"size": "12x12"
},
"sku": "BE-HON-12",
"price_cents": null,
"stock": 4,
"active": true
}
Réponses
- 201 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 409 Conflict
- 422 Validation error
- 429 Rate limited
Exemple de réponse (201)
{
"id": "honey|12x12",
"sku": "BE-HON-12",
"price_cents": 1500,
"stock": 4,
"shared_stock": false,
"options": {
"colour": "honey",
"size": "12x12"
},
"active": true,
"available": true
}
Essayez avec curl
curl -X POST "https://demarkstudio.ca/api/v1/products/1/variants" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"options": {"colour": "honey", "size": "12x12"}, "sku": "BE-HON-12", "price_cents": null, "stock": 4, "active": true}'
Retour à l'index
PATCH
/api/v1/products/{product_id}/variants/{variant_id}
Modifier une variante (prix, stock, active)
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
product_id |
chemin |
integer |
Oui |
Product id. |
variant_id |
chemin |
string |
Oui |
Variant id, '|' URL-encoded as %7C. |
Corps de la requête
| Nom | Type | Obligatoire | Description |
sku |
string | null |
Non |
|
price_cents |
integer | null |
Non |
null = calculated. |
stock |
integer | null |
Non |
Absolute own stock; null = shares the product stock. Not together with stock_delta. |
stock_delta |
integer | null |
Non |
Adds to the stock the variant uses (its own or the shared one). Refused with 422 insufficient_stock if it would go below 0. |
active |
boolean | null |
Non |
|
Exemple de corps
{
"sku": "BE-HON-12",
"price_cents": 2500,
"stock": null,
"stock_delta": -2,
"active": false
}
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": "honey|12x12",
"sku": "BE-HON-12",
"price_cents": 1500,
"stock": 4,
"shared_stock": false,
"options": {
"colour": "honey",
"size": "12x12"
},
"active": true,
"available": true
}
Essayez avec curl
curl -X PATCH "https://demarkstudio.ca/api/v1/products/1/variants/string" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"sku": "BE-HON-12", "price_cents": 2500, "stock": null, "stock_delta": -2, "active": false}'
Retour à l'index
GET
/api/v1/shop/policies
Lire les politiques de livraison et de retour
Fonctionne avec une clé publique
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
lang |
requête |
string | null |
Non |
en or fr. |
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"lang": "en",
"shipping": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
},
"returns": {
"text": "We ship across New Brunswick for $12.00.",
"paragraphs": [
"We ship across New Brunswick for $12.00."
],
"url": "https://demarkstudio.ca/salon-ana/shop/shipping"
}
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/shop/policies" \
-H "Authorization: Bearer dmk_pk_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
Orders
Shop orders and their status.
GET
/api/v1/orders
Lister les commandes
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
status |
requête |
string | null |
Non |
Only orders in this status (pending_payment, paid, preparing, ready, shipped, delivered, cancelled, refunded, paid_after_cancel). |
since |
requête |
string | null |
Non |
Created at or after this ISO date or datetime. |
cursor |
requête |
string | null |
Non |
|
limit |
requête |
integer |
Non |
|
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"data": [
{
"id": 18,
"number": "O-2026-0018",
"status": "pending_payment",
"customer": {
"name": null,
"email": null,
"phone": null
},
"delivery": "pickup",
"subtotal": "40.00",
"shipping": "0.00",
"tax": "6.00",
"total": "46.00",
"currency": "CAD",
"items": [
null
],
"created_at": "2026-09-14T10:02:11-03:00",
"customer_id": 31,
"subtotal_cents": 4000,
"shipping_cents": 0,
"tax_cents": 600,
"taxes": [
null
],
"total_cents": 4600,
"lines": [
null
],
"allowed_transitions": [
"paid",
"cancelled"
]
}
],
"next_cursor": null
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/orders" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
GET
/api/v1/orders/{order_id}
Lire une commande
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
order_id |
chemin |
integer |
Oui |
|
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 18,
"number": "O-2026-0018",
"status": "pending_payment",
"customer": {
"name": "Lea Roy",
"email": "lea@example.com",
"phone": ""
},
"delivery": "pickup",
"subtotal": "40.00",
"shipping": "0.00",
"tax": "6.00",
"total": "46.00",
"currency": "CAD",
"items": [
{
"product_id": 9,
"name": "Cedar candle",
"price": "20.00",
"qty": 2
}
],
"created_at": "2026-09-14T10:02:11-03:00",
"customer_id": 31,
"subtotal_cents": 4000,
"shipping_cents": 0,
"tax_cents": 600,
"taxes": [
{
"name": "GST",
"rate": 5.0,
"registration_number": "123456789 RT0001",
"amount_cents": 300
}
],
"total_cents": 4600,
"lines": [
{
"product_id": 9,
"variant_id": "honey|12x12",
"name": "Bird's eye vinyl",
"options": {
"colour": "honey",
"size": "12x12"
},
"options_label": "Colour: Honey maple, Size: 12 x 12 in",
"qty": 2,
"unit_price_cents": 1500,
"total_cents": 3000
}
],
"allowed_transitions": [
"paid",
"cancelled"
],
"history": [
{
"status": "paid",
"at": "2026-09-14T10:05:00-03:00",
"source": "system"
}
]
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/orders/1" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
PATCH
/api/v1/orders/{order_id}/status
Changer le statut d'une commande
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
order_id |
chemin |
integer |
Oui |
|
Corps de la requête
| Nom | Type | Obligatoire | Description |
status |
string |
Oui |
preparing, ready, shipped, delivered, cancelled, refunded, or paid (only with manual_payment). |
manual_payment |
boolean |
Non |
Required (true) to mark an order paid: payment taken outside DeMark. Audited. |
tracking |
string | null |
Non |
Tracking number for shipped. |
Exemple de corps
{
"status": "shipped",
"manual_payment": false,
"tracking": "CA123456789"
}
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, scope or plan
- 404 Not found
- 409 Conflict
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 18,
"number": "O-2026-0018",
"status": "pending_payment",
"customer": {
"name": "Lea Roy",
"email": "lea@example.com",
"phone": ""
},
"delivery": "pickup",
"subtotal": "40.00",
"shipping": "0.00",
"tax": "6.00",
"total": "46.00",
"currency": "CAD",
"items": [
{
"product_id": 9,
"name": "Cedar candle",
"price": "20.00",
"qty": 2
}
],
"created_at": "2026-09-14T10:02:11-03:00",
"customer_id": 31,
"subtotal_cents": 4000,
"shipping_cents": 0,
"tax_cents": 600,
"taxes": [
{
"name": "GST",
"rate": 5.0,
"registration_number": "123456789 RT0001",
"amount_cents": 300
}
],
"total_cents": 4600,
"lines": [
{
"product_id": 9,
"variant_id": "honey|12x12",
"name": "Bird's eye vinyl",
"options": {
"colour": "honey",
"size": "12x12"
},
"options_label": "Colour: Honey maple, Size: 12 x 12 in",
"qty": 2,
"unit_price_cents": 1500,
"total_cents": 3000
}
],
"allowed_transitions": [
"paid",
"cancelled"
],
"history": [
{
"status": "paid",
"at": "2026-09-14T10:05:00-03:00",
"source": "system"
}
]
}
Essayez avec curl
curl -X PATCH "https://demarkstudio.ca/api/v1/orders/1/status" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"status": "shipped", "manual_payment": false, "tracking": "CA123456789"}'
Retour à l'index
Invoices
Invoices and their payments.
GET
/api/v1/invoices
Lister les factures
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
cursor |
requête |
string | null |
Non |
|
limit |
requête |
integer |
Non |
|
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"data": [
{
"id": 42,
"number": "2026-0042",
"status": "issued",
"customer": {
"name": null,
"email": null,
"phone": null
},
"currency": "CAD",
"base": "1200.00",
"tax": "180.00",
"taxes": [
null
],
"total": "1380.00",
"due_date": "2026-10-14",
"paid_at": null,
"lines": [
null
],
"payments": [
null
],
"created_at": "2026-09-14T10:02:11-03:00"
}
],
"next_cursor": null
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/invoices" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
GET
/api/v1/invoices/{invoice_id}
Lire une facture
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
invoice_id |
chemin |
integer |
Oui |
|
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 404 Not found
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 42,
"number": "2026-0042",
"status": "issued",
"customer": {
"name": "Lea Roy",
"email": "lea@example.com",
"phone": ""
},
"currency": "CAD",
"base": "1200.00",
"tax": "180.00",
"taxes": [
{
"name": "GST",
"rate": 5.0,
"registration_number": "123456789 RT0001",
"amount": "60.00"
}
],
"total": "1380.00",
"due_date": "2026-10-14",
"paid_at": null,
"lines": [
{
"concept": "Kitchen cabinets",
"detail": "",
"qty": 1.0,
"unit_price": "1200.00",
"amount": "1200.00",
"tax_exempt": false
}
],
"payments": [
{
"provider": "stripe",
"amount": "1380.00",
"currency": "CAD",
"status": "paid",
"reference": "pi_3Nk...",
"created_at": "2026-09-14T10:02:11-03:00"
}
],
"created_at": "2026-09-14T10:02:11-03:00"
}
Essayez avec curl
curl -X GET "https://demarkstudio.ca/api/v1/invoices/1" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Retour à l'index
POST
/api/v1/invoices/{invoice_id}/mark-paid
Marquer une facture comme payée
Clé secrète seulement
Paramètres
| Nom | Dans | Type | Obligatoire | Description |
invoice_id |
chemin |
integer |
Oui |
|
Idempotency-Key |
en-tête |
string |
Non |
Retry safely: the first 2xx response is kept 24 hours and replayed with Idempotent-Replayed: true. Same key with a different body: 422 idempotency_key_reused. |
Corps de la requête
| Nom | Type | Obligatoire | Description |
method |
string |
Oui |
|
reference |
string | null |
Non |
|
paid_at |
string | null |
Non |
ISO 8601; defaults to now. |
Exemple de corps
{
"method": "e-transfer",
"reference": "ET-88213",
"paid_at": null
}
Réponses
- 200 Successful Response
- 401 Missing, invalid or revoked API key
- 403 Forbidden: key type, permission, origin or plan
- 404 Not found
- 409 Conflict
- 422 Validation error
- 429 Rate limited
Exemple de réponse (200)
{
"id": 42,
"number": "2026-0042",
"status": "issued",
"customer": {
"name": "Lea Roy",
"email": "lea@example.com",
"phone": ""
},
"currency": "CAD",
"base": "1200.00",
"tax": "180.00",
"taxes": [
{
"name": "GST",
"rate": 5.0,
"registration_number": "123456789 RT0001",
"amount": "60.00"
}
],
"total": "1380.00",
"due_date": "2026-10-14",
"paid_at": null,
"lines": [
{
"concept": "Kitchen cabinets",
"detail": "",
"qty": 1.0,
"unit_price": "1200.00",
"amount": "1200.00",
"tax_exempt": false
}
],
"payments": [
{
"provider": "stripe",
"amount": "1380.00",
"currency": "CAD",
"status": "paid",
"reference": "pi_3Nk...",
"created_at": "2026-09-14T10:02:11-03:00"
}
],
"created_at": "2026-09-14T10:02:11-03:00"
}
Essayez avec curl
curl -X POST "https://demarkstudio.ca/api/v1/invoices/1/mark-paid" \
-H "Authorization: Bearer dmk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{"method": "e-transfer", "reference": "ET-88213", "paid_at": null}'
Retour à l'index
Modèles
Les objets que renvoie l'API et qu'envoient les webhooks. Les dates portent le décalage horaire de votre entreprise, les montants sont des chaînes décimales et chaque valeur est la valeur publique en anglais.
Booking
Champs de Booking
| Nom | Type | Obligatoire | Description |
id |
integer |
Oui |
|
status |
string |
Oui |
pending, confirmed, cancelled, completed or no_show. |
start |
string |
Oui |
ISO 8601 with the business offset. |
end |
string |
Oui |
|
service |
ServiceRef | null |
Oui |
null when the service was deleted. |
staff |
StaffRef | null |
Oui |
null when anyone can do it. |
location |
LocationRef | null |
Oui |
Where it takes place (GET /locations). start and end carry the business offset; the location time zone is here. |
customer |
CustomerRef |
Oui |
|
notes |
string | null |
Oui |
|
lang |
string | null |
Oui |
en or fr: the language of the booking and its emails. |
source |
string | null |
Oui |
Where it was made: web, api, panel, portal... |
created_at |
string | null |
Oui |
|
Exemple réel
{
"id": 1,
"status": "confirmed",
"start": "2026-10-09T09:00:00-03:00",
"end": "2026-10-09T09:45:00-03:00",
"service": {
"id": 3,
"name": "Coupe"
},
"staff": {
"id": 1,
"name": "Julie"
},
"location": {
"id": 2,
"name": "Salon Ana",
"timezone": "America/Moncton"
},
"customer": {
"name": "Marie Tremblay",
"email": "marie.tremblay@mail.test",
"phone": "506 555 0123"
},
"notes": "First visit",
"lang": "fr",
"source": "api",
"created_at": "2026-10-02T23:24:52-03:00"
}
NewBooking
Champs de NewBooking
| Nom | Type | Obligatoire | Description |
id |
integer |
Oui |
|
status |
string |
Oui |
pending, confirmed, cancelled, completed or no_show. |
start |
string |
Oui |
ISO 8601 with the business offset. |
end |
string |
Oui |
|
service |
ServiceRef | null |
Oui |
null when the service was deleted. |
staff |
StaffRef | null |
Oui |
null when anyone can do it. |
location |
LocationRef | null |
Oui |
Where it takes place (GET /locations). start and end carry the business offset; the location time zone is here. |
customer |
CustomerRef |
Oui |
|
notes |
string | null |
Oui |
|
lang |
string | null |
Oui |
en or fr: the language of the booking and its emails. |
source |
string | null |
Oui |
Where it was made: web, api, panel, portal... |
created_at |
string | null |
Oui |
|
token |
string |
Oui |
Management token. Shown once: store it to read or cancel the booking. |
manage_url |
string |
Oui |
Page where the visitor manages the booking. |
cancel_url |
string |
Oui |
Page where the visitor confirms the cancellation (GET, no key). Servers cancel with DELETE /bookings/{id}?token=... or with a secret key. |
payment_url |
string | null |
Oui |
Deposit or card checkout, when the service asks for it. |
Exemple réel
{
"id": 1,
"status": "confirmed",
"start": "2026-10-09T09:00:00-03:00",
"end": "2026-10-09T09:45:00-03:00",
"service": {
"id": 3,
"name": "Coupe"
},
"staff": {
"id": 1,
"name": "Julie"
},
"location": {
"id": 2,
"name": "Salon Ana",
"timezone": "America/Moncton"
},
"customer": {
"name": "Marie Tremblay",
"email": "marie.tremblay@mail.test",
"phone": "506 555 0123"
},
"notes": "First visit",
"lang": "fr",
"source": "api",
"created_at": "2026-10-02T23:24:52-03:00",
"token": "IfnZPtmgcfpabtYFc_UU4AxdOWc1MHHGjdUU-jrbLAA",
"manage_url": "https://demarkstudio.ca/citas/IfnZPtmgcfpabtYFc_UU4AxdOWc1MHHGjdUU-jrbLAA",
"cancel_url": "https://demarkstudio.ca/citas/IfnZPtmgcfpabtYFc_UU4AxdOWc1MHHGjdUU-jrbLAA/cancel",
"payment_url": null
}
Request
Champs de Request
| Nom | Type | Obligatoire | Description |
id |
integer |
Oui |
|
type |
string |
Oui |
quote, contact or support (also lead, booking, question, event, table_booking, other for requests that came from other channels). |
status |
string |
Oui |
new, open, waiting_customer, resolved or closed. |
subject |
string |
Oui |
|
message |
string |
Oui |
What the customer wrote, without page or file lines. |
customer |
CustomerRef |
Oui |
|
page_url |
string | null |
Oui |
Page the request was sent from, when known. |
attachments |
array[Attachment] |
Oui |
Empty when there are none. |
lang |
string | null |
Oui |
|
source |
string |
Oui |
api, web, site, chat, email... |
created_at |
string |
Oui |
|
Exemple réel
{
"id": 1,
"type": "quote",
"status": "new",
"subject": "Wedding party, 6 people",
"message": "Hair and make-up for six people on a Saturday morning.",
"customer": {
"name": "Marc Leblanc",
"email": "marc.leblanc@mail.test",
"phone": "506 555 0199"
},
"page_url": "https://www.your-salon.ca/weddings",
"attachments": [
{
"id": 1,
"filename": "inspiration.png",
"content_type": "image/png",
"size": 69,
"url": "https://demarkstudio.ca/adjuntos/2/1?exp=1791253492&sig=c376ff521d8e24efa9fa372d1b46bd445c99acfc839ccd051a54d04c9dff4c3f",
"expires_at": "2026-10-05T23:24:52-03:00"
}
],
"lang": "fr",
"source": "api",
"created_at": "2026-10-02T23:24:52-03:00"
}
Attachment
Champs de Attachment
| Nom | Type | Obligatoire | Description |
id |
integer |
Oui |
|
filename |
string |
Oui |
|
content_type |
string |
Oui |
|
size |
integer |
Oui |
Bytes. |
url |
string |
Oui |
Signed download link; no key needed until expires_at. |
expires_at |
string |
Oui |
ISO 8601; ask for the request again to get a fresh url. |
Exemple réel
{
"id": 1,
"filename": "inspiration.png",
"content_type": "image/png",
"size": 69,
"url": "https://demarkstudio.ca/adjuntos/2/1?exp=1791253492&sig=c376ff521d8e24efa9fa372d1b46bd445c99acfc839ccd051a54d04c9dff4c3f",
"expires_at": "2026-10-05T23:24:52-03:00"
}
Customer
Champs de Customer
| Nom | Type | Obligatoire | Description |
id |
integer |
Oui |
|
name |
string |
Oui |
|
email |
string |
Oui |
|
phone |
string |
Oui |
|
company |
string |
Oui |
|
lang |
string |
Oui |
|
notes |
string |
Oui |
|
marketing_consent |
boolean |
Oui |
|
created_at |
string | null |
Oui |
|
Exemple réel
{
"id": 2,
"name": "Marie Tremblay",
"email": "marie.tremblay@mail.test",
"phone": "506 555 0123",
"company": "",
"lang": "fr",
"notes": "Prefers mornings",
"marketing_consent": false,
"created_at": "2026-10-02T23:24:52-03:00"
}
Order
Champs de Order
| Nom | Type | Obligatoire | Description |
id |
integer |
Oui |
|
number |
string |
Oui |
|
status |
string |
Oui |
pending_payment, paid, preparing, ready, shipped, delivered, cancelled, refunded or paid_after_cancel. |
customer |
CustomerRef |
Oui |
|
delivery |
string |
Oui |
pickup, shipping, digital or empty. |
subtotal |
string |
Oui |
|
shipping |
string |
Oui |
|
tax |
string |
Oui |
|
total |
string |
Oui |
|
currency |
string |
Oui |
|
items |
array[OrderItem] |
Oui |
|
created_at |
string |
Oui |
|
Exemple réel
{
"id": 1,
"number": "O-2026-0001",
"status": "paid",
"customer": {
"name": "Lea Roy",
"email": "lea.roy@mail.test",
"phone": ""
},
"delivery": "pickup",
"subtotal": "40.00",
"shipping": "0.00",
"tax": "0.00",
"total": "40.00",
"currency": "CAD",
"items": [
{
"product_id": 1,
"name": "Cedar candle",
"price": "20.00",
"qty": 2
}
],
"created_at": "2026-10-02T23:24:52-03:00"
}
Event
Champs de Event
| Nom | Type | Obligatoire | Description |
id |
string |
Oui |
Occurrence id: <event_id>-<YYYY-MM-DD>. |
event_id |
integer |
Oui |
|
title |
string |
Oui |
In the requested language. |
description |
string |
Oui |
|
start |
string |
Oui |
|
end |
string |
Oui |
|
seats_left |
integer | null |
Oui |
null = no capacity limit. |
price |
string | null |
Oui |
|
currency |
string |
Oui |
|
url |
string |
Oui |
Event page in the requested language. |
Exemple réel
{
"id": "1-2026-10-14",
"event_id": 1,
"title": "Atelier de soins capillaires",
"description": "Deux heures pour apprendre une routine qui dure.",
"start": "2026-10-14T18:00:00-03:00",
"end": "2026-10-14T20:00:00-03:00",
"seats_left": 12,
"price": "25.00",
"currency": "CAD",
"url": "https://demarkstudio.ca/salon-ana/events/hair-care-workshop?ocurrencia=2026-10-14&lang=fr"
}
Service
Champs de Service
| Nom | Type | Obligatoire | Description |
id |
integer |
Oui |
|
name |
string |
Oui |
In the requested language. |
description |
string |
Oui |
|
duration_min |
integer |
Oui |
|
price |
string | null |
Oui |
Decimal as string, or null when the service has no price. |
currency |
string |
Oui |
|
staff |
array[StaffRef] |
Oui |
Who can do it; empty when the business has no team. |
image_url |
string | null |
Oui |
|
Exemple réel
{
"id": 3,
"name": "Coupe",
"description": "Lavage, coupe et coiffage.",
"duration_min": 45,
"price": "45.00",
"currency": "CAD",
"staff": [
{
"id": 1,
"name": "Julie"
}
],
"image_url": null
}
Product
Champs de Product
| Nom | Type | Obligatoire | Description |
id |
integer |
Oui |
|
name |
string |
Oui |
|
description |
string |
Oui |
|
price |
string | null |
Oui |
|
currency |
string |
Oui |
|
image_url |
string | null |
Oui |
|
url |
string |
Oui |
Product page in the requested language. |
stock |
integer | null |
Oui |
null = unlimited. |
variants |
array[object] |
Oui |
Active variants (id, sku, price_cents, stock, options, active, available); empty when the product has no options. |
Exemple réel
{
"id": 1,
"name": "Bougie au cedre",
"description": "",
"price": "20.00",
"currency": "CAD",
"image_url": null,
"url": "https://demarkstudio.ca/salon-ana/shop/cedar-candle?lang=fr",
"stock": 10,
"variants": []
}
Corps des webhooks
Chaque corps ci-dessous a été généré par DeMark à partir d'une réservation, d'une demande, d'une commande et d'un client de test. data est le même modèle que celui de l'API REST : une seule classe dans votre code lit les deux.
La version 1 ne fait qu'ajouter des champs : ignorez ceux que vous ne connaissez pas. created reste un alias UTC de created_at pour les anciens récepteurs.
POST booking.created
Une réservation est confirmée, qu'elle vienne d'un widget, de l'API, de votre page de réservation ou de l'arrière-boutique. data est un WebhookBooking
{
"business": {
"id": 2,
"slug": "salon-ana"
},
"created": "2026-10-03T02:24:52.567Z",
"created_at": "2026-10-02T23:24:52-03:00",
"data": {
"created_at": "2026-10-02T23:24:52-03:00",
"customer": {
"email": "marie.tremblay@mail.test",
"name": "Marie Tremblay",
"phone": "506 555 0123"
},
"end": "2026-10-09T09:45:00-03:00",
"id": 1,
"lang": "fr",
"location": {
"id": 2,
"name": "Salon Ana",
"timezone": "America/Moncton"
},
"manage_url": "https://demarkstudio.ca/citas/c2-1-12f82226c4db44f694f2343dd1942d94",
"notes": "First visit",
"service": {
"id": 3,
"name": "Coupe"
},
"source": "api",
"staff": {
"id": 1,
"name": "Julie"
},
"start": "2026-10-09T09:00:00-03:00",
"status": "confirmed"
},
"id": "evt_2",
"type": "booking.created"
}
Retour à l'index
POST booking.cancelled
Une réservation est annulée, par le client ou par vous. data est un WebhookBooking
{
"business": {
"id": 2,
"slug": "salon-ana"
},
"created": "2026-10-03T02:24:52.609Z",
"created_at": "2026-10-02T23:24:52-03:00",
"data": {
"created_at": "2026-10-02T23:24:52-03:00",
"customer": {
"email": "luc.arsenault@mail.test",
"name": "Luc Arsenault",
"phone": ""
},
"end": "2026-10-09T10:45:00-03:00",
"id": 2,
"lang": "en",
"location": {
"id": 2,
"name": "Salon Ana",
"timezone": "America/Moncton"
},
"manage_url": "https://demarkstudio.ca/citas/c2-2-dcd2cbc1d9ca3db5593cd8364bf6349b",
"notes": "",
"service": {
"id": 3,
"name": "Haircut"
},
"source": "api",
"staff": {
"id": 1,
"name": "Julie"
},
"start": "2026-10-09T10:00:00-03:00",
"status": "cancelled"
},
"id": "evt_5",
"type": "booking.cancelled"
}
Retour à l'index
POST request.created
Une demande de soumission, de contact ou de soutien arrive. data est un Request
{
"business": {
"id": 2,
"slug": "salon-ana"
},
"created": "2026-10-03T02:24:52.624Z",
"created_at": "2026-10-02T23:24:52-03:00",
"data": {
"attachments": [
{
"content_type": "image/png",
"expires_at": "2026-10-05T23:24:52-03:00",
"filename": "inspiration.png",
"id": 1,
"size": 69,
"url": "https://demarkstudio.ca/adjuntos/2/1?exp=1791253492&sig=c376ff521d8e24efa9fa372d1b46bd445c99acfc839ccd051a54d04c9dff4c3f"
}
],
"created_at": "2026-10-02T23:24:52-03:00",
"customer": {
"email": "marc.leblanc@mail.test",
"name": "Marc Leblanc",
"phone": "506 555 0199"
},
"id": 1,
"lang": "fr",
"message": "Hair and make-up for six people on a Saturday morning.",
"page_url": "https://www.your-salon.ca/weddings",
"source": "api",
"status": "new",
"subject": "Wedding party, 6 people",
"type": "quote"
},
"id": "evt_7",
"type": "request.created"
}
Retour à l'index
POST order.paid
Une commande est payée. data est un Order
{
"business": {
"id": 2,
"slug": "salon-ana"
},
"created": "2026-10-03T02:24:52.652Z",
"created_at": "2026-10-02T23:24:52-03:00",
"data": {
"created_at": "2026-10-02T23:24:52-03:00",
"currency": "CAD",
"customer": {
"email": "lea.roy@mail.test",
"name": "Lea Roy",
"phone": ""
},
"delivery": "pickup",
"id": 1,
"items": [
{
"name": "Cedar candle",
"price": "20.00",
"product_id": 1,
"qty": 2
}
],
"number": "O-2026-0001",
"shipping": "0.00",
"status": "paid",
"subtotal": "40.00",
"tax": "0.00",
"total": "40.00"
},
"id": "evt_10",
"type": "order.paid"
}
Retour à l'index
POST customer.created
Un nouveau client est ajouté. data est un Customer
{
"business": {
"id": 2,
"slug": "salon-ana"
},
"created": "2026-10-03T02:24:52.552Z",
"created_at": "2026-10-02T23:24:52-03:00",
"data": {
"company": "",
"created_at": "2026-10-02T23:24:52-03:00",
"email": "marie.tremblay@mail.test",
"id": 2,
"lang": "fr",
"marketing_consent": false,
"name": "Marie Tremblay",
"notes": "Prefers mornings",
"phone": "506 555 0123"
},
"id": "evt_1",
"type": "customer.created"
}
Retour à l'index
POST order.created
Une commande est passée, avant son paiement. data est un Order
{
"business": {
"id": 2,
"slug": "salon-ana"
},
"created": "2026-10-03T02:24:52.645Z",
"created_at": "2026-10-02T23:24:52-03:00",
"data": {
"created_at": "2026-10-02T23:24:52-03:00",
"currency": "CAD",
"customer": {
"email": "lea.roy@mail.test",
"name": "Lea Roy",
"phone": ""
},
"delivery": "pickup",
"id": 1,
"items": [
{
"name": "Cedar candle",
"price": "20.00",
"product_id": 1,
"qty": 2
}
],
"number": "O-2026-0001",
"shipping": "0.00",
"status": "pending_payment",
"subtotal": "40.00",
"tax": "0.00",
"total": "40.00"
},
"id": "evt_9",
"type": "order.created"
}
Retour à l'index
POST invoice.paid
Une facture est marquée comme payée. data est un WebhookInvoice
{
"business": {
"id": 2,
"slug": "salon-ana"
},
"created": "2026-10-03T02:24:52.731Z",
"created_at": "2026-10-02T23:24:52-03:00",
"data": {
"base": "510.00",
"created_at": "2026-10-02T23:24:52-03:00",
"currency": "CAD",
"customer": {
"email": "marie.tremblay@mail.test",
"name": "Marie Tremblay",
"phone": null
},
"due_date": "2026-11-01",
"id": 1,
"lines": [
{
"amount": "510.00",
"concept": "Wedding party",
"detail": "Hair and make-up, 6 people",
"qty": 6.0,
"tax_exempt": false,
"unit_price": "85.00"
}
],
"number": "2026-0001",
"paid_at": "2026-10-02T23:24:52-03:00",
"status": "paid",
"tax": "76.37",
"taxes": [
{
"amount": "25.50",
"name": "GST",
"rate": 5.0,
"registration_number": "123456789 RT0001"
},
{
"amount": "50.87",
"name": "QST",
"rate": 9.975,
"registration_number": "1234567890 TQ0001"
}
],
"total": "586.37"
},
"id": "evt_11",
"type": "invoice.paid"
}
Retour à l'index