curl --request POST \
--url https://api.dentalspace.ai/v1/webhook-endpoints \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "<string>",
"events": [],
"description": "<string>"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({url: '<string>', events: [], description: '<string>'})
};
fetch('https://api.dentalspace.ai/v1/webhook-endpoints', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.dentalspace.ai/v1/webhook-endpoints"
payload = {
"url": "<string>",
"events": [],
"description": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"url": "<string>",
"description": "<string>",
"events": [
"patient.created"
],
"enabled": true,
"disabledReason": "manual",
"consecutiveFailures": 0,
"previousSecretExpiresAt": "<string>",
"secretRotatedAt": "<string>",
"createdAt": "<string>",
"updatedAt": "<string>",
"secret": "<string>"
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}Crea una destinazione dei webhook
Scope: webhooks:write.
Al massimo 20 per clinica. Il segreto si vede solo nella risposta. Gli eventi sono filtrati con gli scope e le sedi di QUESTA chiave. Ogni webhook e’ un POST JSON firmato: calcola HMAC-SHA256(segreto, “v1\n” + X-DentalSpace-Timestamp + “\n” + X-DentalSpace-Idempotency-Key + “\n” + corpo) e confrontalo con uno dei valori v1= di X-DentalSpace-Signature; rifiuta i timestamp piu’ vecchi di 5 minuti e scarta le Idempotency-Key gia’ viste. Rispondi 2xx entro 10 secondi; altrimenti si ritenta dopo 1, 5, 15 minuti e 1 ora. I redirect non si seguono.
curl --request POST \
--url https://api.dentalspace.ai/v1/webhook-endpoints \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"url": "<string>",
"events": [],
"description": "<string>"
}
'const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({url: '<string>', events: [], description: '<string>'})
};
fetch('https://api.dentalspace.ai/v1/webhook-endpoints', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));import requests
url = "https://api.dentalspace.ai/v1/webhook-endpoints"
payload = {
"url": "<string>",
"events": [],
"description": "<string>"
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text){
"id": "3c90c3cc-0d44-4b50-8888-8dd25736052a",
"url": "<string>",
"description": "<string>",
"events": [
"patient.created"
],
"enabled": true,
"disabledReason": "manual",
"consecutiveFailures": 0,
"previousSecretExpiresAt": "<string>",
"secretRotatedAt": "<string>",
"createdAt": "<string>",
"updatedAt": "<string>",
"secret": "<string>"
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}{
"error": {
"code": "invalid_request",
"message": "<string>",
"details": {},
"requestId": "<string>"
}
}Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
https, con un nome pubblico: indirizzi privati, locali o con credenziali si rifiutano.
1 - 20481 - 50 elementsUn tipo di evento del catalogo.
patient.created, patient.updated, patient.archived, appointment.created, appointment.rescheduled, appointment.confirmed, appointment.cancelled, appointment.checked_in, appointment.completed, appointment.no_show, treatment_plan.presented, treatment_plan.accepted, treatment_plan.rejected, invoice.issued, invoice.paid, payment.received, installment.overdue, lead.created, lead.converted, task.created, task.completed, conversation.message_received, conversation.handoff_requested, call.logged 200Response
La destinazione, con il segreto.
^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{4}-[0-9a-fA-F]{12})$Un tipo di evento del catalogo.
patient.created, patient.updated, patient.archived, appointment.created, appointment.rescheduled, appointment.confirmed, appointment.cancelled, appointment.checked_in, appointment.completed, appointment.no_show, treatment_plan.presented, treatment_plan.accepted, treatment_plan.rejected, invoice.issued, invoice.paid, payment.received, installment.overdue, lead.created, lead.converted, task.created, task.completed, conversation.message_received, conversation.handoff_requested, call.logged too_many_failures: spenta dopo 50 consegne scartate di fila. Riaccendila con PATCH enabled=true.
manual, too_many_failures -9007199254740991 <= x <= 9007199254740991Fino a quest'istante si firma anche con il segreto precedente.
whsec_...: si vede SOLO in questa risposta. Conservalo.