Skip to content

Managing channels

Channels are managed entirely over the tenant-scoped REST API. A channel is a concrete provider you enable and attach credentials to; palumb stores the config encrypted and resolves it at send time by kind.

ActionEndpointSuccess
List what’s availableGET /v1/channels/catalog200
List your enabled channels (safe view)GET /v1/channels200
Enable + configure (idempotent)POST /v1/channels201
Replace config / toggle enabledPATCH /v1/channels/:key200
RemoveDELETE /v1/channels/:key204

All examples assume PALUMB_API_KEY and a base URL (here http://localhost:3000).

The catalog declares each available channel and the config fields it expects — their names, types, whether they’re required, and whether they’re secret:

Terminal window
curl -sS http://localhost:3000/v1/channels/catalog \
-H "Authorization: Bearer $PALUMB_API_KEY"

Today it returns one entry, email-smtp (kind email). Use the field list as the source of truth for what config must contain.

POST /v1/channels enables a catalog channel and stores your credentials (encrypted at rest; never returned):

Terminal window
curl -sS http://localhost:3000/v1/channels \
-H "Authorization: Bearer $PALUMB_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"channelKey": "email-smtp",
"config": {
"host": "smtp.example.com",
"port": 587,
"secure": false,
"username": "apikey",
"password": "secret",
"fromEmail": "noreply@example.com",
"fromName": "Example"
},
"priority": 0
}'
FieldRequiredNotes
channelKeyMust exist in the catalog
configValidated against the catalog schema; secrets encrypted
enabledDefaults to true
priority>= 0, defaults to 0; lower is tried first
FieldTypeRequiredSecret
hoststring
portnumber
securebooleantrue = implicit TLS (465); false = STARTTLS/plain (587, 1025)
usernamestringomit for an unauthenticated relay
passwordstring✓ stored encrypted
fromEmailstringsender address
fromNamestringoptional display name

POST is idempotent on (tenant, channelKey) — calling it again updates the existing channel (and re-enables it) rather than creating a duplicate. A config that fails the schema (unknown field, missing required, wrong type) is a 422; an unknown channelKey is a 404.

Terminal window
curl -sS http://localhost:3000/v1/channels \
-H "Authorization: Bearer $PALUMB_API_KEY"

The response is a safe view — it confirms a channel exists and is configured but never echoes a secret:

[
{ "channelKey": "email-smtp", "kind": "email", "label": "Email (SMTP)",
"enabled": true, "priority": 0, "configured": true, "createdAt": "" }
]

PATCH /v1/channels/:key changes config and/or the enabled flag. At least one of the two must be present (otherwise 400):

Terminal window
# Rotate the SMTP password — config is a FULL replacement, not a merge.
curl -sS -X PATCH http://localhost:3000/v1/channels/email-smtp \
-H "Authorization: Bearer $PALUMB_API_KEY" \
-H 'Content-Type: application/json' \
-d '{ "config": { "host": "smtp.example.com", "port": 587, "secure": false,
"username": "apikey", "password": "NEW-secret",
"fromEmail": "noreply@example.com", "fromName": "Example" } }'
# Disable without touching config:
curl -sS -X PATCH http://localhost:3000/v1/channels/email-smtp \
-H "Authorization: Bearer $PALUMB_API_KEY" \
-H 'Content-Type: application/json' \
-d '{ "enabled": false }'

If you enable more than one channel of the same kind, palumb picks the lowest priority at send time (ties broken by oldest first), skipping disabled ones. Give a backup relay a higher number (e.g. primary 0, backup 10) so it’s only chosen when the primary is gone.

Terminal window
curl -sS -X DELETE http://localhost:3000/v1/channels/email-smtp \
-H "Authorization: Bearer $PALUMB_API_KEY"

Returns 204. A workflow that then sends on a kind with no enabled channel gets a terminal failure.