The SMG Tools API
Read and write a business’s clients, jobs, leads and appointments, read its invoices, and subscribe to what happens, from any program the business gives a key.
Get started
A key is made by the business, not by you. Its owner opens Integrations → API keys in SMG Tools, chooses New key, names it after the program it is for and ticks what it may do. The key is shown once; they copy it to you or paste it into the program. Every plan can issue keys.
Send the key with every request as a bearer token. The API answers at
https://smg-api.smgtools.com/v1, in JSON:
curl 'https://smg-api.smgtools.com/v1/me' \
-H 'Authorization: Bearer smgk_…' That call works for any key and says which business it belongs to, the key’s name and what it may do — a good first request, and the one a program makes to show which account it is connected to.
A key sees the whole business, as a manager does, and does only what its scopes allow. What it writes goes through the same rules as the business’s own work, with the same effects, and the record says the key did it: a client added through the API says Zapier (API key) added it, and a job it completes runs the business’s automations for a completed job just as the office completing it would. A key never charges, refunds or deletes, and never sends an invoice, a proposal or a message of its own.
What a key may do
Each route needs one scope, and a key has the ones the business ticked when it made the key. A request for
anything else is refused with scope_required, naming the scope it needed.
Any key may call GET /v1/me and GET /v1/webhooks/events, whatever it was allowed.
Errors
Every error is application/problem+json in one shape: the HTTP status, a stable
code to branch on, a title a person can read, the scope a key lacked,
and errors — each field’s problems — when a write was refused. A code is never
renamed; new ones may be added, so treat one you do not know by its status.
{
"status": 422,
"code": "validation_failed",
"title": "En Route and On Site can only be reported by a worker assigned to the job, from the field view",
"errors": {
"status": ["En Route and On Site can only be reported by a worker assigned to the job, from the field view"]
}
} | Code | Status | Means |
|---|---|---|
invalid_key | 401 | No key was sent, or it is not one any business issued. Keys begin smgk_. |
key_revoked | 401 | The business revoked the key. Ask them for a new one. |
scope_required | 403 | The key was not allowed this when it was issued. The problem’s scope names the one it lacks. |
not_found | 404 | Nothing at this address in the business — a record it does not have, or one this key may not see. |
validation_failed | 422 | A rule refused the request. The title says why in a sentence, and errors names each field’s problems, all at once. |
checklist_outstanding | 422 | A job cannot be completed while a required checklist step is unanswered, unless checklistOverrideReason says why. |
idempotency_conflict | 409 | The Idempotency-Key was sent before with a different request, or its first request is still being answered. |
rate_limited | 429 | Too many requests. Wait the seconds in the Retry-After header, then try again. |
invalid_request | 400 | The request could not be read: a body that is not JSON, a parameter of the wrong kind, an Idempotency-Key over 255 characters. |
method_not_allowed | 405 | The address does not take that method. |
internal_error | 500 | Something went wrong on our side. A create sent with an Idempotency-Key is safe to retry. |
Lists, paging and syncing
Every list answers a page at a time: data, with page, pageSize and
total. Ask for a page with page (from 1) and pageSize (up to 100).
Lists are oldest first, so a page you have read does not change under you as records are added.
Every list takes updatedSince, an instant: only the records created or changed at or after it
are returned. A program that keeps a copy in step asks for what changed since its last sync, rather than
reading everything again. Times are UTC instants; a date is the business’s own calendar day.
Retrying a create
Send an Idempotency-Key header — any value up to 255 characters, new for each thing you
mean to create — with every create. If the answer is lost and you send the same request with the same
key again within 24 hours, you are given the first answer rather than a second record, with the header
Idempotent-Replayed: true. The same key with a different request is refused as
idempotency_conflict.
Limits
Each key may make 120 requests a minute, and a business 600 a minute across all its keys. A request past
either is refused with rate_limited and a Retry-After header in seconds. A business
may have twenty working keys.
Checking a webhook came from us
A key allowed webhooks:write can subscribe an address to events — see
Webhooks below. Each delivery is a POST of JSON with the headers
X-SmgTools-Event, X-SmgTools-Delivery-Id, X-SmgTools-Timestamp and
X-SmgTools-Signature. The signature reads t={timestamp},v1={signature}:
an HMAC-SHA256, in lowercase hex, of the timestamp, a period and the raw body, keyed with the subscription’s
secret exactly as it was given to you, whsec_ and all.
// Node.js
const [t, v1] = header.split(',').map((part) => part.split('=')[1]);
const expected = crypto.createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
const genuine = crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(v1)); Compare against the body as it arrived, before parsing it, and refuse a timestamp more than a few minutes old so a delivery cannot be replayed. The secret is in the answer that created the subscription and never again.
Versions and the contract
This is version 1. Within it we only add — a new route, a new field, a new error code — so a program should ignore a field it does not know. Anything that would break a program comes in a new version, with notice before the old one is retired.
The API describes itself in OpenAPI 3.1 at https://smg-api.smgtools.com/v1/openapi.json, for any tool that generates a client from it. The reference below is written from the same document.
Me
Which business and which key is calling, and what the key may do
GET /v1/me any key
Answers 200 with Me.
curl -X GET 'https://smg-api.smgtools.com/v1/me' \
-H 'Authorization: Bearer smgk_…' The Me record
| Field | Type | Notes |
|---|---|---|
business | Business | |
key | Key |
The Business record
| Field | Type | Notes |
|---|---|---|
id | string (uuid) | |
name | string |
The Key record
| Field | Type | Notes |
|---|---|---|
id | string (uuid) | |
name | string | |
scopes | array of string |
Clients
The business's clients, a page at a time, oldest first
GET /v1/clients clients:read
Archived clients are left out unless includeArchived is true. updatedSince returns only the clients created or changed at or after that instant — what a sync asks for.
| Parameter | In | Type |
|---|---|---|
page | query | integer |
pageSize | query | integer |
updatedSince | query | string (date-time) |
includeArchived | query | boolean |
Answers 200 with a page of Client; may refuse 403.
curl -X GET 'https://smg-api.smgtools.com/v1/clients' \
-H 'Authorization: Bearer smgk_…' Add a client
POST /v1/clients clients:write
The client's source is Integration, labelled with the key's name, and its history says the key added it. Send an Idempotency-Key to make a retry safe.
| Field | Type | Notes |
|---|---|---|
name (required) | string | |
businessName | string | |
email | string | |
phone | string | |
address | string | |
notes | string |
Answers 201 with Client; may refuse 403, 409, 422.
curl -X POST 'https://smg-api.smgtools.com/v1/clients' \
-H 'Authorization: Bearer smgk_…' \
-H 'Idempotency-Key: 7c1f0d52-first-try' \
-H 'Content-Type: application/json' \
-d '{"name":"Marisol Rivera"}' One client
GET /v1/clients/{id} clients:read
| Parameter | In | Type |
|---|---|---|
id (required) | path | string (uuid) |
Answers 200 with Client; may refuse 403, 404.
curl -X GET 'https://smg-api.smgtools.com/v1/clients/3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10' \
-H 'Authorization: Bearer smgk_…' Change a client's details
PATCH /v1/clients/{id} clients:write
A field left out is left as it is. An archived client cannot be changed.
| Parameter | In | Type |
|---|---|---|
id (required) | path | string (uuid) |
| Field | Type | Notes |
|---|---|---|
name | string | |
businessName | string | |
email | string | |
phone | string | |
address | string | |
notes | string |
Answers 200 with Client; may refuse 403, 404, 422.
curl -X PATCH 'https://smg-api.smgtools.com/v1/clients/3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10' \
-H 'Authorization: Bearer smgk_…' \
-H 'Content-Type: application/json' \
-d '{"name":"Marisol Rivera","businessName":"Marisol Rivera"}' The Client record
| Field | Type | Notes |
|---|---|---|
id | string (uuid) | |
name | string | |
businessName | string, or null | |
email | string, or null | |
phone | string, or null | |
address | string, or null | |
notes | string, or null | |
archived | boolean | Archived clients are hidden from the business's lists and are listed here only when asked for. |
source | string | The door the client came through, such as Integration, PublicPageDirect or Manual. |
sourceLabel | string, or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time), or null |
Jobs
The business's jobs, a page at a time, oldest first
GET /v1/jobs jobs:read
Narrow by status and clientId. Archived jobs are left out unless includeArchived is true. updatedSince returns only the jobs created or changed at or after that instant.
| Parameter | In | Type |
|---|---|---|
page | query | integer |
pageSize | query | integer |
updatedSince | query | string (date-time) |
status | query | string |
clientId | query | string (uuid) |
includeArchived | query | boolean |
Answers 200 with a page of Job; may refuse 403.
curl -X GET 'https://smg-api.smgtools.com/v1/jobs' \
-H 'Authorization: Bearer smgk_…' Create a job for one of the business's clients
POST /v1/jobs jobs:write
The job's history says the key created it, and it goes on the business's board, calendar and webhooks exactly as one created in the console. Send an Idempotency-Key to make a retry safe.
| Field | Type | Notes |
|---|---|---|
clientId (required) | string (uuid) | |
title (required) | string | |
description | string | |
number | string | Left out, the business's next number is given. |
jobTypeId | string (uuid) | Left out, the business's default job type. |
status | string | Left out, Planning. EnRoute and OnSite are the crew's to report and are refused. |
startDate | string (date) | |
targetCompletionDate | string (date) | |
agreedPrice | number | |
location | string | |
priority | string | |
notes | string | |
customerReference | string |
Answers 201 with Job; may refuse 403, 409, 422.
curl -X POST 'https://smg-api.smgtools.com/v1/jobs' \
-H 'Authorization: Bearer smgk_…' \
-H 'Idempotency-Key: 7c1f0d52-first-try' \
-H 'Content-Type: application/json' \
-d '{"clientId":"3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10","title":"Water heater swap"}' One job
GET /v1/jobs/{id} jobs:read
| Parameter | In | Type |
|---|---|---|
id (required) | path | string (uuid) |
Answers 200 with Job; may refuse 403, 404.
curl -X GET 'https://smg-api.smgtools.com/v1/jobs/3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10' \
-H 'Authorization: Bearer smgk_…' Change a job's details
PATCH /v1/jobs/{id} jobs:write
A field left out is left as it is; an empty string clears a text field. The status changes on its own route.
| Parameter | In | Type |
|---|---|---|
id (required) | path | string (uuid) |
| Field | Type | Notes |
|---|---|---|
clientId | string (uuid) | |
title | string | |
description | string | |
number | string | |
jobTypeId | string (uuid) | |
startDate | string (date) | |
targetCompletionDate | string (date) | |
agreedPrice | number | |
location | string | |
priority | string | |
notes | string | |
customerReference | string |
Answers 200 with Job; may refuse 403, 404, 422.
curl -X PATCH 'https://smg-api.smgtools.com/v1/jobs/3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10' \
-H 'Authorization: Bearer smgk_…' \
-H 'Content-Type: application/json' \
-d '{"clientId":"3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10","title":"Water heater swap"}' Move a job to another status, as the office does
POST /v1/jobs/{id}/status jobs:write
The same checks as the console's: a job with a required checklist step unanswered cannot be Completed without a checklistOverrideReason (checklist_outstanding), and EnRoute and OnSite are the crew's to report.
| Parameter | In | Type |
|---|---|---|
id (required) | path | string (uuid) |
| Field | Type | Notes |
|---|---|---|
status (required) | string | Planning, Approved, InProgress, OnHold, Completed or Closed. |
actualCompletionDate | string (date) | When it was finished, for Completed; today in the business's time zone when left out. |
checklistOverrideReason | string | Why the job may be finished with its checklist incomplete. Refused without one while anything required is outstanding. |
Answers 200 with Job; may refuse 403, 404, 422.
curl -X POST 'https://smg-api.smgtools.com/v1/jobs/3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10/status' \
-H 'Authorization: Bearer smgk_…' \
-H 'Content-Type: application/json' \
-d '{"status":"InProgress"}' The Job record
| Field | Type | Notes |
|---|---|---|
id | string (uuid) | |
number | string | The job's number in the business, such as J-0042. |
clientId | string (uuid) | |
jobTypeId | string (uuid) | |
title | string | |
description | string, or null | |
status | string | One of Planning, Approved, InProgress, OnHold, EnRoute, OnSite, Completed, Closed. EnRoute and OnSite are the crew's to report. |
startDate | string (date), or null | |
targetCompletionDate | string (date), or null | |
actualCompletionDate | string (date), or null | |
billingBasis | string, or null | AgreedPrice, AsItGoes, or null when the business has not said. |
agreedPrice | number, or null | The price agreed for the job, when it is billed at one. |
location | string, or null | |
priority | string, or null | Low, Medium, High or Urgent. |
notes | string, or null | |
customerReference | string, or null | The customer's own reference for the work — a purchase order, a work order. |
archived | boolean | |
createdAt | string (date-time) | |
updatedAt | string (date-time), or null |
Leads
The business's leads, a page at a time, oldest first
GET /v1/leads leads:read
Narrow by status. Archived leads are left out unless includeArchived is true or the status asked for is Archived. updatedSince returns only the leads created, contacted, converted or archived at or after that instant.
| Parameter | In | Type |
|---|---|---|
page | query | integer |
pageSize | query | integer |
updatedSince | query | string (date-time) |
status | query | string |
includeArchived | query | boolean |
Answers 200 with a page of Lead; may refuse 403.
curl -X GET 'https://smg-api.smgtools.com/v1/leads' \
-H 'Authorization: Bearer smgk_…' Add a lead
POST /v1/leads leads:write
Through the same door as the business's public form and its inbound lead address: the same rules, every problem named at once. Its source is Integration, labelled with the key's name. Send an Idempotency-Key to make a retry safe.
| Field | Type | Notes |
|---|---|---|
name | string | |
email | string | |
phone | string | |
address | string | |
descriptionOfWork | string | |
preferredContactMethod | string | Email, Phone or Text. |
preferredTimeOfDay | string | Morning, Afternoon or Evening. |
preferredDate | string (date) | |
preferredTimeWindow | string |
Answers 201 with Lead; may refuse 403, 409, 422.
curl -X POST 'https://smg-api.smgtools.com/v1/leads' \
-H 'Authorization: Bearer smgk_…' \
-H 'Idempotency-Key: 7c1f0d52-first-try' \
-H 'Content-Type: application/json' \
-d '{"name":"Marisol Rivera","email":"marisol@example.com"}' One lead
GET /v1/leads/{id} leads:read
| Parameter | In | Type |
|---|---|---|
id (required) | path | string (uuid) |
Answers 200 with Lead; may refuse 403, 404.
curl -X GET 'https://smg-api.smgtools.com/v1/leads/3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10' \
-H 'Authorization: Bearer smgk_…' Move a lead, as the Leads page does
POST /v1/leads/{id}/status leads:write
New to Contacted and back, to Archived from any, and an archived lead restored to Contacted. A lead becomes Converted only by becoming a client.
| Parameter | In | Type |
|---|---|---|
id (required) | path | string (uuid) |
| Field | Type | Notes |
|---|---|---|
status (required) | string | New, Contacted or Archived. |
Answers 200 with Lead; may refuse 403, 404, 422.
curl -X POST 'https://smg-api.smgtools.com/v1/leads/3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10/status' \
-H 'Authorization: Bearer smgk_…' \
-H 'Content-Type: application/json' \
-d '{"status":"InProgress"}' The Lead record
| Field | Type | Notes |
|---|---|---|
id | string (uuid) | |
name | string | |
email | string, or null | |
phone | string, or null | |
address | string, or null | |
descriptionOfWork | string, or null | |
preferredContactMethod | string, or null | |
preferredTimeOfDay | string, or null | |
preferredDate | string (date), or null | |
preferredTimeWindow | string, or null | |
source | string | The door the lead came through, such as Integration, PublicPageDirect, Referral or InboundCall. |
sourceLabel | string, or null | What that door was called — for a lead a key made, the key's name. |
status | string | New, Contacted, Converted or Archived. |
clientId | string (uuid), or null | The client the lead became, or belongs to. |
createdAt | string (date-time) | |
contactedAt | string (date-time), or null | |
convertedAt | string (date-time), or null | |
archivedAt | string (date-time), or null |
Appointments
The business's appointments, a page at a time, oldest booked first
GET /v1/appointments appointments:read
Narrow to dates from and to, inclusive, on the business's own calendar. Cancelled appointments are left out unless includeCancelled is true. updatedSince returns only the appointments booked, changed or cancelled at or after that instant.
| Parameter | In | Type |
|---|---|---|
page | query | integer |
pageSize | query | integer |
updatedSince | query | string (date-time) |
from | query | string (date) |
to | query | string (date) |
includeCancelled | query | boolean |
Answers 200 with a page of Appointment; may refuse 403.
curl -X GET 'https://smg-api.smgtools.com/v1/appointments' \
-H 'Authorization: Bearer smgk_…' Book an appointment against one of the business's jobs or clients
POST /v1/appointments appointments:write
On the business's own clock and its calendar, with its reminders and, when asked, its email to the client. Send an Idempotency-Key to make a retry safe.
| Field | Type | Notes |
|---|---|---|
title (required) | string | |
date (required) | string (date) | |
startTime | string (time) | Needed unless allDay is true. |
endTime | string (time) | An hour after the start when left out. |
allDay (required) | boolean | |
location | string | |
notes | string | |
jobId | string (uuid) | |
clientId | string (uuid) | |
reminderEnabled | boolean | Left out, true. |
notifyClient | boolean | Send the client an email that the visit is booked. Left out, false. |
Answers 201 with Appointment; may refuse 403, 409, 422.
curl -X POST 'https://smg-api.smgtools.com/v1/appointments' \
-H 'Authorization: Bearer smgk_…' \
-H 'Idempotency-Key: 7c1f0d52-first-try' \
-H 'Content-Type: application/json' \
-d '{"title":"Water heater swap","date":"2026-10-01","startTime":"09:00:00","allDay":false}' One appointment
GET /v1/appointments/{id} appointments:read
| Parameter | In | Type |
|---|---|---|
id (required) | path | string (uuid) |
Answers 200 with Appointment; may refuse 403, 404.
curl -X GET 'https://smg-api.smgtools.com/v1/appointments/3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10' \
-H 'Authorization: Bearer smgk_…' Reschedule an appointment, or change its details
PATCH /v1/appointments/{id} appointments:write
A field left out is left as it is; an empty string clears the location or the notes; allDay true drops the times.
| Parameter | In | Type |
|---|---|---|
id (required) | path | string (uuid) |
| Field | Type | Notes |
|---|---|---|
title | string | |
date | string (date) | |
startTime | string (time) | |
endTime | string (time) | |
allDay | boolean | |
location | string | |
notes | string | |
reminderEnabled | boolean |
Answers 200 with Appointment; may refuse 403, 404, 422.
curl -X PATCH 'https://smg-api.smgtools.com/v1/appointments/3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10' \
-H 'Authorization: Bearer smgk_…' \
-H 'Content-Type: application/json' \
-d '{"title":"Water heater swap","date":"2026-10-01"}' Cancel an appointment
POST /v1/appointments/{id}/cancel appointments:write
It stays on record as cancelled; nothing is deleted. Cancelling a cancelled appointment answers it as it is.
| Parameter | In | Type |
|---|---|---|
id (required) | path | string (uuid) |
Answers 200 with Appointment; may refuse 403, 404.
curl -X POST 'https://smg-api.smgtools.com/v1/appointments/3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10/cancel' \
-H 'Authorization: Bearer smgk_…' The Appointment record
| Field | Type | Notes |
|---|---|---|
id | string (uuid) | |
title | string | |
date | string (date) | |
startTime | string (time), or null | |
endTime | string (time), or null | |
allDay | boolean | |
start | string (date-time), or null | |
end | string (date-time), or null | |
location | string, or null | |
notes | string, or null | |
jobId | string (uuid), or null | |
clientId | string (uuid), or null | |
reminderEnabled | boolean | Whether the client is sent a reminder before the visit. |
cancelled | boolean | |
createdAt | string (date-time) | |
updatedAt | string (date-time), or null | |
cancelledAt | string (date-time), or null |
Invoices
The business's invoices, with their lines, payments and balance, a page at a time
GET /v1/invoices invoices:read
Narrow by status, clientId and jobId. updatedSince returns only the invoices raised or changed at or after that instant. Nothing on v1 writes an invoice.
| Parameter | In | Type |
|---|---|---|
page | query | integer |
pageSize | query | integer |
updatedSince | query | string (date-time) |
status | query | string |
clientId | query | string (uuid) |
jobId | query | string (uuid) |
Answers 200 with a page of Invoice; may refuse 403.
curl -X GET 'https://smg-api.smgtools.com/v1/invoices' \
-H 'Authorization: Bearer smgk_…' One invoice, with its lines, payments and balance
GET /v1/invoices/{id} invoices:read
| Parameter | In | Type |
|---|---|---|
id (required) | path | string (uuid) |
Answers 200 with Invoice; may refuse 403, 404.
curl -X GET 'https://smg-api.smgtools.com/v1/invoices/3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10' \
-H 'Authorization: Bearer smgk_…' The Invoice record
| Field | Type | Notes |
|---|---|---|
id | string (uuid) | |
number | string | The invoice's number in the business, such as INV-0042. |
clientId | string (uuid) | |
jobId | string (uuid), or null | |
status | string | Draft, Sent, Viewed, PartiallyPaid, Paid, Overdue or Voided. |
issueDate | string (date) | The date printed on the invoice. |
dueDate | string (date), or null | |
lines | array of InvoiceLine | |
subtotal | number | |
taxRate | number, or null | The tax rate as a percentage, such as 8.25; null when the invoice is not taxed. |
tax | number | |
total | number | |
amountPaid | number | Everything paid, tips excluded. |
balance | number | What is still owed: the total less what has been paid. |
payments | array of Payment | |
customerReference | string, or null | |
notes | string, or null | |
sentAt | string (date-time), or null | |
paidAt | string (date-time), or null | |
voidedAt | string (date-time), or null | |
createdAt | string (date-time) | |
updatedAt | string (date-time), or null |
The InvoiceLine record
| Field | Type | Notes |
|---|---|---|
description | string | |
quantity | number, or null | |
unitPrice | number, or null | |
hours | number, or null | |
hourlyRate | number, or null | |
total | number |
The Payment record
| Field | Type | Notes |
|---|---|---|
id | string (uuid) | |
amount | number | |
tip | number | A tip given with the payment, on top of the amount. |
method | string | How it was paid, such as Card, Cash, Check or BankTransfer. |
receivedAt | string (date-time) | |
voided | boolean | A voided payment no longer counts toward what is paid. |
Webhooks
The events a subscription may be sent, with the fields each carries
GET /v1/webhooks/events any key
Answers 200 with WebhookEvent.
curl -X GET 'https://smg-api.smgtools.com/v1/webhooks/events' \
-H 'Authorization: Bearer smgk_…' The subscriptions this key made
GET /v1/webhooks webhooks:write
Only this key's: a subscription a person or another key made is theirs.
Answers 200 with Webhook; may refuse 403.
curl -X GET 'https://smg-api.smgtools.com/v1/webhooks' \
-H 'Authorization: Bearer smgk_…' Subscribe an address to events
POST /v1/webhooks webhooks:write
The console's rules: an https address on the public internet, events from the catalog, at most ten subscriptions per business; the address is checked again before every delivery. The signing secret is in this answer and never again. Send an Idempotency-Key to make a retry safe.
| Field | Type | Notes |
|---|---|---|
url (required) | string | |
events (required) | array of string |
Answers 201 with CreatedWebhook; may refuse 403, 409, 422.
curl -X POST 'https://smg-api.smgtools.com/v1/webhooks' \
-H 'Authorization: Bearer smgk_…' \
-H 'Idempotency-Key: 7c1f0d52-first-try' \
-H 'Content-Type: application/json' \
-d '{"url":"https://example.com/hooks/smg","events":["lead.created"]}' Remove a subscription this key made
DELETE /v1/webhooks/{id} webhooks:write
Nothing already sent is recalled. A subscription the key did not make is not found.
| Parameter | In | Type |
|---|---|---|
id (required) | path | string (uuid) |
Answers 204; may refuse 403, 404.
curl -X DELETE 'https://smg-api.smgtools.com/v1/webhooks/3f2c9a1e-5b7d-4c2a-9e61-0a8d4b2c7f10' \
-H 'Authorization: Bearer smgk_…' The WebhookEvent record
| Field | Type | Notes |
|---|---|---|
name | string | |
description | string | |
fields | array of string |
The Webhook record
| Field | Type | Notes |
|---|---|---|
id | string (uuid) | |
url | string | |
events | array of string | The events it is sent, by name from the catalog at /v1/webhooks/events. |
status | string | Active; Paused, when the platform stopped after failed deliveries and the business has to resume it; or Disabled. |
createdAt | string (date-time) |
The CreatedWebhook record
| Field | Type | Notes |
|---|---|---|
webhook | Webhook | |
secret | string | Verifies each delivery's X-SmgTools-Signature: t=<timestamp>,v1=<hex>, where v1 is HMAC-SHA256 of <timestamp>.<body> under this secret. |
The business’s side — making a key, choosing what it may do, seeing what it has been doing and revoking it — is in the help page Connect a program with an API key. Use of the API is on the Terms of Use, section 8.13.