GET /portal/api/webhooks
Webhook subscriptions
Host https://app.socialmatterspay.com
Responses
| Status | Meaning |
|---|---|
200 | OK |
401 | Error — error shape and codes |
Fields of each item of data (200)
| Field | Notes |
|---|---|
idstring | — |
urlstring | — |
eventsarray of enum | one of payment.authorized, payment.declined, payment.settled, payment.released, payment.returned, payment.voided, payment.refunded, payout.initiated, payout.settled, payout.failed, fee.assessed, invoice.paid, invoice.partially_paid, invoice.overdue, bank_account.disconnected, bank_account.relink_required, bank_account.relink_recommended, bank_account.owner_changed, * |
activeenum | 1: on; 0: turned off. one of 0, 1 |
created_atstring (date-time) | — |
deliveriesinteger | How many deliveries have been made to it, including test events |
last_delivered_atstring | null (date-time) | When a delivery last reached it; null if none has |
Example
Dashboard webhooks
curl https://app.socialmatterspay.com/portal/api/webhooks \
-H 'Authorization: Bearer portal_session_token'
HTTP 200
Cache-Control: no-store
{
"data": [
{
"id": "a4602568-d7c4-46ee-9f8b-b7d99c853837",
"url": "https://northwind.example/smp/webhooks",
"events": [
"payment.authorized",
"payment.settled",
… 6 more
],
"active": 0,
"created_at": "2026-10-28T00:22:34.449Z",
"deliveries": 18,
"last_delivered_at": "2026-10-28T00:22:37.605Z"
},
{
"id": "713306de-3d17-443b-9ec7-5c136d7251e3",
"url": "https://northwind.example/smp/dashboard-hooks",
"events": [
"payment.settled"
],
"active": 1,
"created_at": "2026-10-28T00:22:37.923Z",
"deliveries": 0,
"last_delivered_at": null
}
],
"events": [
"payment.authorized",
"payment.declined",
… 17 more
]
}
POST /portal/api/webhooks
Create a webhook subscription (HTTPS only); the signing secret is shown once
Host https://app.socialmatterspay.com
Request body
| Field | Notes |
|---|---|
url requiredstring (uri) | — |
events requiredarray of string | — |
Responses
| Status | Meaning |
|---|---|
201 | OK |
400 | Error — error shape and codes |
401 | Error — error shape and codes |
Fields of data (201)
| Field | Notes |
|---|---|
objectstring = "webhook_subscription" | — |
idstring | — |
secretstring | The signing secret, shown only here: whsec_ followed by 64 hex characters |
urlstring | — |
eventsarray of enum | one of payment.authorized, payment.declined, payment.settled, payment.released, payment.returned, payment.voided, payment.refunded, payout.initiated, payout.settled, payout.failed, fee.assessed, invoice.paid, invoice.partially_paid, invoice.overdue, bank_account.disconnected, bank_account.relink_required, bank_account.relink_recommended, bank_account.owner_changed, * |
activeboolean = true | — |
Example
Add a webhook from the dashboard
curl -X POST https://app.socialmatterspay.com/portal/api/webhooks \
-H 'Authorization: Bearer portal_session_token' \
-H 'Content-Type: application/json' \
-d '{
"url": "https://northwind.example/smp/dashboard-hooks",
"events": [
"payment.settled"
]
}'
HTTP 201
Cache-Control: no-store
{
"data": {
"object": "webhook_subscription",
"id": "713306de-3d17-443b-9ec7-5c136d7251e3",
"secret": "whsec_…",
"url": "https://northwind.example/smp/dashboard-hooks",
"events": [
"payment.settled"
],
"active": true
}
}
GET /portal/api/settings
Merchant settings and limits
Host https://app.socialmatterspay.com
Responses
| Status | Meaning |
|---|---|
200 | OK |
401 | Error — error shape and codes |
Fields of data (200)
| Field | Notes | ||||||
|---|---|---|---|---|---|---|---|
namestring | — | ||||||
legal_namestring | — | ||||||
statement_descriptorstring | — | ||||||
payout_scheduleenum | one of daily, weekly, biweekly, monthly, hold | ||||||
payout_weekdayinteger | null | The weekday a weekly or every-other-week payout goes out, 1 (Monday) to 5 (Friday); null when staff set none. 1 to 5 | ||||||
limit_per_txn_centsinteger | — | ||||||
limit_daily_centsinteger | — | ||||||
limit_monthly_centsinteger | — | ||||||
pricing_classenum | one of standard, high_risk | ||||||
statusenum | A login on an account in any other status cannot sign in. one of approved, active, terminated | ||||||
website_urlstring | null | — | ||||||
categorystring | null | — | ||||||
api_key_prefixstring | The first characters of the account's main API key | ||||||
payout_account_on_fileboolean | — | ||||||
payout_account_typeenum | one of checking, savings, | ||||||
payout_account_holder_namestring | null | — | ||||||
payout_daysstring | The payout schedule in words, for example 'only when you ask (no fee)' | ||||||
portal_emailstring | The signed-in login's address | ||||||
environmentenum | one of production, sandbox | ||||||
limits_in_forceobject | What a payment is checked against now: the per-payment and daily limits halved (rounded down) while the return rate is critical or worse, or a small merchant is on step 2 or 3; the monthly limit is never halved3 child fields
| ||||||
limits_halved_becauseobject | null | Why the limits are halved; null when they are not3 child fields
|
Example
Dashboard settings
curl https://app.socialmatterspay.com/portal/api/settings \
-H 'Authorization: Bearer portal_session_token'
HTTP 200
Cache-Control: no-store
{
"data": {
"name": "Northwind Supply",
"legal_name": "Northwind Supply LLC",
"statement_descriptor": "NORTHWIND",
"payout_schedule": "weekly",
"payout_weekday": null,
"limit_per_txn_cents": 300000,
"limit_daily_cents": 5000000,
"limit_monthly_cents": 50000000,
"pricing_class": "standard",
"status": "active",
"website_url": "https://northwind.example",
"category": "retail",
"api_key_prefix": "sk_sandbox_b8ed",
"payout_account_on_file": true,
"payout_account_type": "checking",
"payout_account_holder_name": "Northwind Supply LLC",
"limits_in_force": {
"per_transaction_cents": 300000,
"daily_cents": 5000000,
"monthly_cents": 50000000
},
"limits_halved_because": null,
"payout_days": "Tuesday (UTC)",
"portal_email": "owner@northwind.example",
"environment": "sandbox"
}
}
POST /portal/api/webhooks/{id}/test
Queue a webhook.test delivery to this subscription
Host https://app.socialmatterspay.com
Parameters
| Field | Notes |
|---|---|
id requiredpath · string | — |
Responses
| Status | Meaning |
|---|---|
202 | OK |
401 | Error — error shape and codes |
404 | Error — error shape and codes |
503 | Error — error shape and codes |
Fields of data (202)
| Field | Notes |
|---|---|
objectstring = "webhook_delivery" | — |
idstring | The delivery's id |
eventstring = "webhook.test" | — |
statusstring = "queued" | — |
Example
Send a signed test event
curl -X POST https://app.socialmatterspay.com/portal/api/webhooks/713306de-3d17-443b-9ec7-5c136d7251e3/test \
-H 'Authorization: Bearer portal_session_token'
HTTP 202
Cache-Control: no-store
{
"data": {
"object": "webhook_delivery",
"id": "56803f4a-58ec-4ab5-a1a1-14ba26ffc08d",
"event": "webhook.test",
"status": "queued"
}
}
GET /portal/api/webhooks/{id}/deliveries
The last 50 deliveries to this subscription
Host https://app.socialmatterspay.com
Parameters
| Field | Notes |
|---|---|
id requiredpath · string | — |
Responses
| Status | Meaning |
|---|---|
200 | OK |
401 | Error — error shape and codes |
404 | Error — error shape and codes |
Fields of each item of data (200)
| Field | Notes |
|---|---|
idstring | — |
eventstring | The event sent, or webhook.test for a test |
status_codeinteger | null | What the endpoint answered; null while no attempt has been answered |
attemptsinteger | — |
max_attemptsinteger | — |
next_retry_atstring | null (date-time) | When the next attempt is due; null once delivered or out of attempts |
delivered_atstring | null (date-time) | — |
failed_atstring | null (date-time) | — |
created_atstring (date-time) | — |
response_excerptstring | null | The first 200 characters of the endpoint's answer |
Example
A webhook's recent deliveries
curl https://app.socialmatterspay.com/portal/api/webhooks/713306de-3d17-443b-9ec7-5c136d7251e3/deliveries \
-H 'Authorization: Bearer portal_session_token'
HTTP 200
Cache-Control: no-store
{
"data": [
{
"id": "56803f4a-58ec-4ab5-a1a1-14ba26ffc08d",
"event": "webhook.test",
"status_code": null,
"attempts": 0,
"max_attempts": 5,
"next_retry_at": null,
"delivered_at": null,
"failed_at": null,
"created_at": "2026-11-04T03:01:24.741Z",
"response_excerpt": null
},
{
"id": "e7518eaa-6b63-4781-9663-95c19466bba3",
"event": "payment.settled",
"status_code": 200,
"attempts": 1,
"max_attempts": 5,
"next_retry_at": null,
"delivered_at": "2026-10-28T00:22:41.661Z",
"failed_at": null,
"created_at": "2026-11-04T03:01:03.656Z",
"response_excerpt": "ok"
},
… 2 more
]
}
POST /portal/api/webhooks/{id}/disable
Turn a webhook subscription off
Host https://app.socialmatterspay.com
Parameters
| Field | Notes |
|---|---|
id requiredpath · string | — |
Responses
| Status | Meaning |
|---|---|
200 | OK |
401 | Error — error shape and codes |
404 | Error — error shape and codes |
Fields of data (200)
| Field | Notes |
|---|---|
objectstring = "webhook_subscription" | — |
idstring | — |
activeboolean = false | — |
Example
Turn a webhook off
curl -X POST https://app.socialmatterspay.com/portal/api/webhooks/713306de-3d17-443b-9ec7-5c136d7251e3/disable \
-H 'Authorization: Bearer portal_session_token'
HTTP 200
Cache-Control: no-store
{
"data": {
"object": "webhook_subscription",
"id": "713306de-3d17-443b-9ec7-5c136d7251e3",
"active": false
}
}
GET /portal/api/api-keys
The account's API keys (prefixes, created, last used; never the secret)
Host https://app.socialmatterspay.com
Responses
| Status | Meaning |
|---|---|
200 | OK |
401 | Error — error shape and codes |
Fields of each item of data (200)
| Field | Notes |
|---|---|
idstring | pattern ^ak_[0-9a-f]{24}$ |
objectstring = "api_key" | — |
labelstring | — |
prefixstring | The first 15 characters of the key |
site_idstring | null | — |
statusenum | expiring = rotated, working until expires_at. one of active, expiring, expired, revoked |
expires_atstring | null (date-time) | — |
revoked_atstring | null (date-time) | — |
last_used_atstring | null (date-time) | To the quarter hour |
created_atstring (date-time) | — |
currentboolean | The key this request came with |
Example
API keys
curl https://app.socialmatterspay.com/portal/api/api-keys \
-H 'Authorization: Bearer portal_session_token'
HTTP 200
Cache-Control: no-store
{
"data": [
{
"id": "ak_cdd8ac3a73ae2e907e98a139",
"object": "api_key",
"label": "Primary",
"prefix": "sk_sandbox_b8ed",
"site_id": null,
"status": "active",
"expires_at": null,
"revoked_at": null,
"last_used_at": "2026-10-28T00:22:34.406Z",
"created_at": "2026-10-28T00:22:34.395Z",
"current": false
},
{
"id": "ak_712aae48d8a5ea7d8c5336bd",
"object": "api_key",
"label": "Wholesale store",
"prefix": "sk_sandbox_7ab3",
"site_id": "site_3d810c4cb0b887ef83ca99c8",
"status": "revoked",
"expires_at": "2026-10-29T00:22:39.874Z",
"revoked_at": "2026-10-28T00:22:39.877Z",
"last_used_at": null,
"created_at": "2026-10-28T00:22:39.867Z",
"current": false
},
{
"id": "ak_0434deede69824be39cff34f",
"object": "api_key",
"label": "Wholesale store",
"prefix": "sk_sandbox_8a81",
"site_id": "site_3d810c4cb0b887ef83ca99c8",
"status": "active",
"expires_at": null,
"revoked_at": null,
"last_used_at": null,
"created_at": "2026-10-28T00:22:39.874Z",
"current": false
}
]
}
POST /portal/api/api-keys
Create an API key; the secret is shown once (asks for the dashboard password again)
Host https://app.socialmatterspay.com
Request body
| Field | Notes |
|---|---|
password requiredstring | — |
labelstring | — |
Responses
| Status | Meaning |
|---|---|
201 | OK |
400 | Error — error shape and codes |
401 | Error — error shape and codes |
403 | Error — error shape and codes |
Fields of data (201)
| Field | Notes |
|---|---|
idstring | pattern ^ak_[0-9a-f]{24}$ |
objectstring = "api_key" | — |
labelstring | — |
prefixstring | The first 15 characters of the key |
site_idstring | null | — |
statusenum | expiring = rotated, working until expires_at. one of active, expiring, expired, revoked |
expires_atstring | null (date-time) | — |
revoked_atstring | null (date-time) | — |
last_used_atstring | null (date-time) | To the quarter hour |
created_atstring (date-time) | — |
currentboolean | The key this request came with |
keystring | sk_live_… or sk_sandbox_…; shown only here |
Example
Make a key (the password re-entered); it is shown once
curl -X POST https://app.socialmatterspay.com/portal/api/api-keys \
-H 'Authorization: Bearer portal_session_token' \
-H 'Content-Type: application/json' \
-d '{
"password": "correct horse battery staple",
"label": "Warehouse app"
}'
HTTP 201
Cache-Control: no-store
{
"data": {
"id": "ak_1e04e8126340e65a91425469",
"object": "api_key",
"label": "Warehouse app",
"prefix": "sk_sandbox_f640",
"site_id": null,
"status": "active",
"expires_at": null,
"revoked_at": null,
"last_used_at": null,
"created_at": "2026-10-28T00:23:01.873Z",
"current": false,
"key": "sk_sandbox_…"
}
}
POST /portal/api/api-keys/{id}/rotate
Rotate a key: a new secret now, the old one keeps working for the overlap (24 hours by default)
Host https://app.socialmatterspay.com
Parameters
| Field | Notes |
|---|---|
id requiredpath · string | — |
Request body
| Field | Notes |
|---|---|
password requiredstring | — |
expires_in_hoursinteger | How long the old key keeps working; 24 when left out. 1 to 168 |
Responses
| Status | Meaning |
|---|---|
201 | The new key, shown once, and when the old one stops working |
400 | Error — error shape and codes |
401 | Error — error shape and codes |
403 | Error — error shape and codes |
404 | Error — error shape and codes |
Fields of data (201)
| Field | Notes | ||||||
|---|---|---|---|---|---|---|---|
idstring | pattern ^ak_[0-9a-f]{24}$ | ||||||
objectstring = "api_key" | — | ||||||
labelstring | — | ||||||
prefixstring | The first 15 characters of the key | ||||||
site_idstring | null | — | ||||||
statusenum | expiring = rotated, working until expires_at. one of active, expiring, expired, revoked | ||||||
expires_atstring | null (date-time) | — | ||||||
revoked_atstring | null (date-time) | — | ||||||
last_used_atstring | null (date-time) | To the quarter hour | ||||||
created_atstring (date-time) | — | ||||||
currentboolean | The key this request came with | ||||||
keystring | sk_live_… or sk_sandbox_…; shown only here | ||||||
replacesobject | The rotated key, which keeps working until expires_at3 child fields
|
Example
Rotate it: the old key works through the overlap
curl -X POST https://app.socialmatterspay.com/portal/api/api-keys/ak_1e04e8126340e65a91425469/rotate \
-H 'Authorization: Bearer portal_session_token' \
-H 'Content-Type: application/json' \
-d '{
"password": "correct horse battery staple"
}'
HTTP 201
Cache-Control: no-store
{
"data": {
"id": "ak_7b32afc645f5952f30378449",
"object": "api_key",
"label": "Warehouse app",
"prefix": "sk_sandbox_14eb",
"site_id": null,
"status": "active",
"expires_at": null,
"revoked_at": null,
"last_used_at": null,
"created_at": "2026-10-28T00:23:01.915Z",
"current": false,
"key": "sk_sandbox_…",
"replaces": {
"id": "ak_1e04e8126340e65a91425469",
"prefix": "sk_sandbox_f640",
"expires_at": "2026-10-29T00:23:01.915Z"
}
}
}
POST /portal/api/api-keys/{id}/revoke
Revoke a key at once (never the account's last key)
Host https://app.socialmatterspay.com
Parameters
| Field | Notes |
|---|---|
id requiredpath · string | — |
Request body
| Field | Notes |
|---|---|
password requiredstring | — |
Responses
| Status | Meaning |
|---|---|
200 | OK |
400 | Error — error shape and codes |
401 | Error — error shape and codes |
403 | Error — error shape and codes |
404 | Error — error shape and codes |
409 | Error — error shape and codes |
Fields of data (200)
The same fields as under portalApiKeys.
Example
Revoke a key
curl -X POST https://app.socialmatterspay.com/portal/api/api-keys/ak_1e04e8126340e65a91425469/revoke \
-H 'Authorization: Bearer portal_session_token' \
-H 'Content-Type: application/json' \
-d '{
"password": "correct horse battery staple"
}'
HTTP 200
Cache-Control: no-store
{
"data": {
"id": "ak_1e04e8126340e65a91425469",
"object": "api_key",
"label": "Warehouse app",
"prefix": "sk_sandbox_f640",
"site_id": null,
"status": "revoked",
"expires_at": "2026-10-29T00:23:01.915Z",
"revoked_at": "2026-10-28T00:23:01.957Z",
"last_used_at": null,
"created_at": "2026-10-28T00:23:01.873Z",
"current": false
}
}
GET /portal/api/sites
The account's sites, each with its own key, descriptor and webhooks
Host https://app.socialmatterspay.com
Responses
| Status | Meaning |
|---|---|
200 | OK |
401 | Error — error shape and codes |
Fields of each item of data (200)
| Field | Notes |
|---|---|
idstring | pattern ^site_[0-9a-f]{24}$ |
objectstring = "site" | — |
namestring | — |
domainstring | null | — |
statement_descriptorstring | null | Appears as SMS*<descriptor> on the site's payments |
statusenum | one of active, disabled |
created_atstring (date-time) | — |
updated_atstring (date-time) | — |
Example
Sites
curl https://app.socialmatterspay.com/portal/api/sites \
-H 'Authorization: Bearer portal_session_token'
HTTP 200
Cache-Control: no-store
{
"data": [
{
"id": "site_3d810c4cb0b887ef83ca99c8",
"object": "site",
"name": "Northwind Wholesale",
"domain": "wholesale.northwind.example",
"statement_descriptor": "NW WHOLESALE",
"status": "disabled",
"created_at": "2026-10-28T00:22:39.860Z",
"updated_at": "2026-10-28T00:22:39.879Z"
}
]
}
