commsharbor
Transactional e-mail and permission-based campaigns, multi-tenant, with a full audit trail.
- 1.0.0
- Version
- remote
- Transport
- 139
- Tools
Security review
Review passedReviewed 1d ago.
- tools: 139 tools scanned
- metadata: scanned
No findings.
Tools (139)
commsharbor_health
Read deployment health and build. Smoke tests wait for their own commit to appear here instead of racing edge propagation.
commsharbor_logout
Revoke the current session. Bootstrap/CSRF must belong to this browser and session. Other product sessions remain active.
commsharbor_me
Read the current account profile and platform role. `user.id` is the shared-account ID. Organizations are not listed here: they live in the shared account, which does not list them inside products yet — open a workspace by its ID with `GET /api/organizations/{organization_id}`.
commsharbor_context
Resolve the active organization identity. Read this before a write when you are not certain which tenant is active. Guessing is how data lands in the wrong organization. An organization API key answers `kind: api_key` with its scopes.
commsharbor_organization_get
Open an organization by id: name, your role and the CommsHarbor plan. This is how a workspace is opened. Name and role come from the shared account (null with an organization API key, which carries neither); the plan is the organization's global entitlement in CommsHarbor.
commsharbor_audit
List tenant audit events. Audit records are never rewritten and never carry recipient PII.
commsharbor_platform_context
Confirm the caller's platform role. Tenant ownership grants nothing here: platform access is a separate, explicit grant.
commsharbor_domains
List sending domains with their last observed state. `status` is what was last OBSERVED at SES and DNS. It does not become `active` because provisioning was requested.
commsharbor_domain_create
Register the organization's exact sending domain and queue SES provisioning. Asking twice does not provision twice. Publish the returned DKIM records, then call `verify` to have the state observed.
commsharbor_domain_get
Read one stored sending-domain resource. This returns what was stored at the last observation. To look again, call `verify`.
commsharbor_domain_verify
Refresh domain readiness from real SES and DNS observations. This is the ONLY operation that can move a domain to `active`, and only because it actually looked.
commsharbor_domain_smoke
Send one controlled smoke to the server-side recipient secret; never accepts a recipient argument. The request never accepts a recipient: the destination is a server-side secret. That is what keeps this from becoming a way to send mail to arbitrary addresses through someone else's verified domain.
commsharbor_domain_deliveries
List a domain's deliveries without recipient addresses.
commsharbor_delivery_get
Read one delivery and its SES MessageId without recipient data. `ses_message_id` is what correlates this record with AWS when you need to chase a message there.
commsharbor_delivery_events
List normalized SES feedback events for one delivery. Open and Click are ADDITIVE: they are recorded alongside delivery state and never overwrite it.
commsharbor_crm_contacts_list
Lists contacts in the tenant CRM — a person in the tenant CRM. Cursor-paginated: limit 1-100, opaque cursor from the previous page. Filters: q, company_id. Needs crm:read on the organization. Every item carries an absolute url. Being in the CRM is not permission to email: consent lives in the `marketing` sub-resource.
commsharbor_crm_contacts_create
Creates a contact in the tenant CRM. Required: email, first_name. Needs crm:write on the organization. Returns the created resource with its absolute url. Being in the CRM is not permission to email: consent lives in the `marketing` sub-resource.
commsharbor_crm_contacts_get
Reads one contact from the tenant CRM. Needs crm:read on the organization. A foreign or missing id answers 404. Being in the CRM is not permission to email: consent lives in the `marketing` sub-resource.
commsharbor_crm_contacts_update
Updates one contact in the tenant CRM; only the fields you send change. Needs crm:write on the organization. A foreign or missing id answers 404. Being in the CRM is not permission to email: consent lives in the `marketing` sub-resource.
commsharbor_crm_contacts_delete
Deletes one contact from the tenant CRM. Needs crm:write on the organization. A foreign or missing id answers 404. Being in the CRM is not permission to email: consent lives in the `marketing` sub-resource.
commsharbor_crm_companies_list
Lists companies in the tenant CRM — an organization in the tenant CRM — a customer of the customer. Cursor-paginated: limit 1-100, opaque cursor from the previous page. Filters: q. Needs crm:read on the organization. Every item carries an absolute url.
commsharbor_crm_companies_create
Creates a company in the tenant CRM. Required: name. Needs crm:write on the organization. Returns the created resource with its absolute url.
commsharbor_crm_companies_get
Reads one company from the tenant CRM. Needs crm:read on the organization. A foreign or missing id answers 404.
commsharbor_crm_companies_update
Updates one company in the tenant CRM; only the fields you send change. Needs crm:write on the organization. A foreign or missing id answers 404.
commsharbor_crm_companies_delete
Deletes one company from the tenant CRM. Needs crm:write on the organization. A foreign or missing id answers 404.
commsharbor_crm_pipelines_list
Lists pipelines in the tenant CRM — a named sequence of stages that deals move through. Cursor-paginated: limit 1-100, opaque cursor from the previous page. Filters: q. Needs crm:read on the organization. Every item carries an absolute url.
commsharbor_crm_pipelines_create
Creates a pipeline in the tenant CRM. Required: name. Needs crm:write on the organization. Returns the created resource with its absolute url.
commsharbor_crm_pipelines_get
Reads one pipeline from the tenant CRM. Needs crm:read on the organization. A foreign or missing id answers 404.
commsharbor_crm_pipelines_update
Updates one pipeline in the tenant CRM; only the fields you send change. Needs crm:write on the organization. A foreign or missing id answers 404.
commsharbor_crm_pipelines_delete
Deletes one pipeline from the tenant CRM. Needs crm:write on the organization. A foreign or missing id answers 404.
commsharbor_crm_deals_list
Lists deals in the tenant CRM — an opportunity moving through a pipeline. Cursor-paginated: limit 1-100, opaque cursor from the previous page. Filters: q, pipeline_id, stage_id, status. Needs crm:read on the organization. Every item carries an absolute url. Money is in minor units: `value_minor: 10000` with `currency: "USD"` is $100.00, not $10,000.
commsharbor_crm_deals_create
Creates a deal in the tenant CRM. Required: title, pipeline_id, stage_id. Needs crm:write on the organization. Returns the created resource with its absolute url. Money is in minor units: `value_minor: 10000` with `currency: "USD"` is $100.00, not $10,000.
commsharbor_crm_deals_get
Reads one deal from the tenant CRM. Needs crm:read on the organization. A foreign or missing id answers 404. Money is in minor units: `value_minor: 10000` with `currency: "USD"` is $100.00, not $10,000.
commsharbor_crm_deals_update
Updates one deal in the tenant CRM; only the fields you send change. Needs crm:write on the organization. A foreign or missing id answers 404. Money is in minor units: `value_minor: 10000` with `currency: "USD"` is $100.00, not $10,000.
commsharbor_crm_deals_delete
Deletes one deal from the tenant CRM. Needs crm:write on the organization. A foreign or missing id answers 404. Money is in minor units: `value_minor: 10000` with `currency: "USD"` is $100.00, not $10,000.
commsharbor_crm_activities_list
Lists activities in the tenant CRM — something that happened with a contact, company or deal. Cursor-paginated: limit 1-100, opaque cursor from the previous page. Filters: q, deal_id, contact_id, company_id, activity_type. Needs crm:read on the organization. Every item carries an absolute url.
commsharbor_crm_activities_create
Creates a activity in the tenant CRM. Required: note. Needs crm:write on the organization. Returns the created resource with its absolute url.
commsharbor_crm_activities_get
Reads one activity from the tenant CRM. Needs crm:read on the organization. A foreign or missing id answers 404.
commsharbor_crm_activities_update
Updates one activity in the tenant CRM; only the fields you send change. Needs crm:write on the organization. A foreign or missing id answers 404.
commsharbor_crm_activities_delete
Deletes one activity from the tenant CRM. Needs crm:write on the organization. A foreign or missing id answers 404.
commsharbor_crm_tasks_list
Lists tasks in the tenant CRM — work someone still has to do in the tenant CRM. Cursor-paginated: limit 1-100, opaque cursor from the previous page. Filters: q, status, deal_id, contact_id, assignee_user_id. Needs crm:read on the organization. Every item carries an absolute url.
commsharbor_crm_tasks_create
Creates a task in the tenant CRM. Required: title. Needs crm:write on the organization. Returns the created resource with its absolute url.
commsharbor_crm_tasks_get
Reads one task from the tenant CRM. Needs crm:read on the organization. A foreign or missing id answers 404.
commsharbor_crm_tasks_update
Updates one task in the tenant CRM; only the fields you send change. Needs crm:write on the organization. A foreign or missing id answers 404.
commsharbor_crm_tasks_delete
Deletes one task from the tenant CRM. Needs crm:write on the organization. A foreign or missing id answers 404.
commsharbor_crm_stages_list
Lists stages in the tenant CRM — one step of a pipeline, addressed under the pipeline it belongs to. Cursor-paginated: limit 1-100, opaque cursor from the previous page. Needs crm:read on the organization. Every item carries an absolute url.
commsharbor_crm_stages_create
Creates a stage in the tenant CRM. Required: name. Needs crm:write on the organization. Returns the created resource with its absolute url.
commsharbor_crm_stages_get
Reads one stage from the tenant CRM. Needs crm:read on the organization. A foreign or missing id answers 404.
commsharbor_crm_stages_update
Updates one stage in the tenant CRM; only the fields you send change. Needs crm:write on the organization. A foreign or missing id answers 404.
commsharbor_crm_stages_delete
Deletes one stage from the tenant CRM. Needs crm:write on the organization. A foreign or missing id answers 404.
commsharbor_platform_crm_leads_list
Lists leads in the platform CRM — a prospective ORGANIZATION in our own funnel — platform CRM is not tenant data. Cursor-paginated: limit 1-100, opaque cursor from the previous page. Filters: q, stage. Needs a human session with the platform_admin grant; tenant ownership does not qualify. Every item carries an absolute url.
commsharbor_platform_crm_leads_create
Creates a lead in the platform CRM. Required: email, name. Needs a human session with the platform_admin grant; tenant ownership does not qualify. Returns the created resource with its absolute url.
commsharbor_platform_crm_leads_get
Reads one lead from the platform CRM. Needs a human session with the platform_admin grant; tenant ownership does not qualify. A foreign or missing id answers 404.
commsharbor_platform_crm_leads_update
Updates one lead in the platform CRM; only the fields you send change. Needs a human session with the platform_admin grant; tenant ownership does not qualify. A foreign or missing id answers 404.
commsharbor_platform_crm_leads_delete
Deletes one lead from the platform CRM. Needs a human session with the platform_admin grant; tenant ownership does not qualify. A foreign or missing id answers 404.
commsharbor_platform_crm_tasks_list
Lists tasks in the platform CRM — work on a platform lead — about a prospective tenant, not about a tenant's customer. Cursor-paginated: limit 1-100, opaque cursor from the previous page. Filters: q, status, lead_id, assignee_user_id. Needs a human session with the platform_admin grant; tenant ownership does not qualify. Every item carries an absolute url.
commsharbor_platform_crm_tasks_create
Creates a task in the platform CRM. Required: title. Needs a human session with the platform_admin grant; tenant ownership does not qualify. Returns the created resource with its absolute url.
commsharbor_platform_crm_tasks_get
Reads one task from the platform CRM. Needs a human session with the platform_admin grant; tenant ownership does not qualify. A foreign or missing id answers 404.
commsharbor_platform_crm_tasks_update
Updates one task in the platform CRM; only the fields you send change. Needs a human session with the platform_admin grant; tenant ownership does not qualify. A foreign or missing id answers 404.
commsharbor_platform_crm_tasks_delete
Deletes one task from the platform CRM. Needs a human session with the platform_admin grant; tenant ownership does not qualify. A foreign or missing id answers 404.
commsharbor_platform_crm_activities_list
Lists activities in the platform CRM — our note about a prospective tenant. Cursor-paginated: limit 1-100, opaque cursor from the previous page. Filters: q. Needs a human session with the platform_admin grant; tenant ownership does not qualify. Every item carries an absolute url.
commsharbor_platform_crm_activities_create
Creates a activity in the platform CRM. Required: note. Needs a human session with the platform_admin grant; tenant ownership does not qualify. Returns the created resource with its absolute url.
commsharbor_platform_crm_activities_get
Reads one activity from the platform CRM. Needs a human session with the platform_admin grant; tenant ownership does not qualify. A foreign or missing id answers 404.
commsharbor_platform_crm_activities_update
Updates one activity in the platform CRM; only the fields you send change. Needs a human session with the platform_admin grant; tenant ownership does not qualify. A foreign or missing id answers 404.
commsharbor_platform_crm_activities_delete
Deletes one activity from the platform CRM. Needs a human session with the platform_admin grant; tenant ownership does not qualify. A foreign or missing id answers 404.
commsharbor_contact_marketing_get
Read consent and preference for a CRM contact. Being in the CRM is not permission to email. This resource is where permission actually lives.
commsharbor_contact_marketing_put
Record permission-based marketing consent. This NEVER restores a previous unsubscribe. If the contact opted out, they stay out and `marketing_enabled` remains false — recording consent after the fact does not undo their decision.
commsharbor_preference_token_create
Create signed preference and unsubscribe URLs. The capability is scoped to one organization and one contact, it expires, and it embeds no email address. Put `marketing_headers` in the message and the unsubscribe works without a login.
commsharbor_preference_get
Read preference through a signed capability. The token IS the credential. It reveals preference state and nothing else — no email address, no CRM record.
commsharbor_preference_unsubscribe
Apply one-click unsubscribe through a signed capability. This is the endpoint mail clients call from the `List-Unsubscribe-Post` header, which is why the body is form-encoded and fixed. Calling it twice is the same as calling it once.
commsharbor_marketing_smoke
Send one controlled permission-based marketing smoke. Like the transactional smoke, the destination is a server-side secret. `contact_id` must be the CRM contact that matches it — you cannot point this at an arbitrary person.
commsharbor_contact_imports
List the contact imports of the organization.
commsharbor_contact_import_preview
Upload and preview a consent-declared CSV. Nothing is created by this call. The consent declaration is mandatory: an import that cannot say why these people may be emailed is an import that does not happen.
commsharbor_contact_import_get
Read one durable contact import and its current counts.
commsharbor_contact_import_confirm
Confirm an import with a mandatory idempotency key. The idempotency key is mandatory here. Reusing it returns the same import and never creates a second Queue message — which is what keeps a retry from importing everyone twice.
commsharbor_contact_import_errors
List the row-numbered errors of one import, so the source file can be fixed.
commsharbor_contact_file_get
Download a tenant CSV before expiry. Files expire seven days after creation. Durable audit and row-level results survive the file.
commsharbor_contacts_export
Create a CSV export of the organization's contacts, retained for seven days.
commsharbor_suppressions
List organization suppressions. Global, organization and SES tenant suppressions are all checked BEFORE quota and before any queue work.
commsharbor_suppression_create
Suppress one recipient inside the active organization.
commsharbor_audiences
List static audiences and saved segments.
commsharbor_audience_create
Create an audience or saved segment. Only allowlisted filter fields are accepted — a saved segment cannot be turned into an arbitrary query over the CRM.
commsharbor_audience_get
Read one audience of this organization.
commsharbor_audience_update
Rename an audience or change its saved filter.
commsharbor_audience_delete
Delete an audience and its memberships. Contacts themselves are untouched.
commsharbor_audience_members
List the contacts currently in one audience.
commsharbor_audience_member_add
Add a CRM contact to a static audience. Only for `static` audiences: a saved segment's membership comes from its filter, not from this route.
commsharbor_audience_member_remove
Remove a contact from a static audience.
commsharbor_templates
List the versioned email templates of the organization.
commsharbor_template_create
Create a canonical block template draft. Creating never publishes. Nothing can send this template until `publish` freezes a version.
commsharbor_template_get
Read one template draft owned by this organization.
commsharbor_template_update
Update one template draft. Editing a draft can never change what a past delivery rendered: published versions are immutable.
commsharbor_template_archive
Archive a template and preserve its versions. Deliveries that referenced a version must keep resolving to it, so archiving hides the draft and keeps the history.
commsharbor_template_publish
Publish an immutable template version. The version's identity is the hash of its compiled content — publishing identical content does not create a second version.
commsharbor_template_versions
List the immutable published versions of a template.
commsharbor_template_preview
Compile and render a safe template preview. `warnings` tells you what was stripped and what would not render — read it before publishing rather than after sending.
commsharbor_template_export
Export the latest published HTML, text and MJML.
commsharbor_template_import_html
Import a safe HTML subset as a draft. Active content, forms and unsafe URLs are rejected, not sanitised-and-kept. What survives is stored as blocks, so an imported template behaves exactly like an authored one.
commsharbor_message_send
Queue one idempotent transactional delivery. Same behaviour and same idempotency as `POST /api/messages`. `X-Organization-Id` is still required with the session and must match the path. Prefer the canonical route.
commsharbor_campaigns
List the campaigns of the organization.
commsharbor_campaign_create
Create a campaign draft. All three must already exist and be usable: a draft cannot be created against an unverified domain or an unpublished template.
commsharbor_campaign_get
Read one campaign, without any recipient data.
commsharbor_campaign_update
Edit, pause, resume or cancel a campaign. Content can only change while the campaign is a draft. After launch this route moves state — the frozen recipient set and the frozen template version do not change.
commsharbor_campaign_launch
Freeze and launch or schedule a campaign idempotently. The freeze happens once and never again: consent, suppressions and audience membership are evaluated at this moment, and the resulting set is what gets sent. Replaying the same Idempotency-Key returns the same campaign and produces no second dispatch.
commsharbor_campaign_report
Reconcile campaign deliveries and feedback. Counts only. Which specific person opened what is not something this API answers.
commsharbor_messaging_settings
Read the organization's timezone and whether marketing is currently paused.
commsharbor_messaging_settings_update
Update timezone or pause state. Pausing is always allowed. Resuming is not: if the pause came from reputation or SES tenant risk, a healthy observation has to exist first.
commsharbor_deliverability
Read deliverability and backlog aggregates. This is the operator's single view of whether sending is healthy. It carries no recipient PII.
commsharbor_domain_report
Read domain delivery and feedback aggregates.
commsharbor_webhooks
List the webhook endpoints of the organization, without their signing secrets.
commsharbor_webhook_create
Create a webhook and reveal its secret once. Deliveries are signed with timestamped HMAC-SHA256 and retried with exponential backoff; what still fails lands in the tenant-scoped dead-letter queue. Store the secret now — it is never shown again.
commsharbor_webhook_get
Read one webhook, without its signing secret.
commsharbor_webhook_disable
Disable a webhook without deleting the evidence of what it already delivered.
commsharbor_webhook_deliveries
List the signed attempts made to one webhook and their retry state.
commsharbor_dead_letters
Inspect nominal dead letters. What ended up here after every retry. Records are addressed by opaque ID and carry no recipient PII.
commsharbor_dead_letter_replay
Replay one campaign or webhook dead letter. One record at a time, addressed explicitly. There is no "replay everything": a bulk replay of an unknown set is how a bad hour becomes a bad day.
commsharbor_billing_catalog
Read plans, prices and x402 network. Public and unauthenticated: an agent should be able to learn what things cost before deciding whether to sign up at all.
commsharbor_billing
Read the organization's plan, limits and global entitlements. Read this before a bulk send: `state.active` says whether sending is allowed and `warning` says when the plan runs out. A new organization's trial starts with its first domain or send (`state.started`).
commsharbor_billing_purchase
Buy a pass or top-up through the house's payment door (credit or x402); 409 while live checkout is off. While `catalog.checkout_live` is false this answers **409 `checkout_disabled`** — nobody is charged by accident; the local dev stack completes it with the house's simulated payment. Otherwise, without payment it answers the standard **402 with `accepts[]`** and both doors (a `cred_…` credit token, or `X-PAYMENT`). What it buys is a global entitlement: a pass runs 30 days (stacked after the current one), a top-up 365 days and needs an active pass. The same payment never grants twice, and the Idempotency-Key makes a credit retry safe.
commsharbor_operations
List current operational alerts without PII. Covers dead letters, backlog, worker and SNS failures, reputation, paused sending, quota and conservative SES/SNS cost capacity — never with recipient PII.
commsharbor_operations_refresh
Refresh alerts, quota and capacity observations. The GET reads what was last stored; this goes and looks again. Same distinction as domain verification.
commsharbor_data_exports
List the tenant data exports, which are retained for seven days.
commsharbor_data_export_create
Create a seven-day tenant JSON export. Scoped to one organization by construction: an export can never contain another tenant's data.
commsharbor_data_export_download
Download one tenant-scoped JSON export before it expires.
commsharbor_deletion_request
Read the latest tenant deletion request. `status: "none"` means no erasure was ever requested — the resource always answers, so a client never has to interpret a 404 as "nothing scheduled".
commsharbor_deletion_schedule
Schedule tenant erasure after seven days using the exact confirmation phrase. The confirmation phrase must be exactly `delete <organization_id>` — typing the id is the point, so nobody erases the wrong tenant by clicking. Erasure deletes the workspace data in CommsHarbor; the organization itself and what it bought (global entitlements, payment receipts) live in the shared account and stay, as does the audit trail.
commsharbor_deletion_cancel
Cancel a scheduled tenant erasure. That is what the seven days are for: after they pass, there is nothing left to cancel.
commsharbor_tracking_domain
Read the organization's tracking domain, the CNAME it needs and whether the platform actually answers on it. Null when there is none: links then use the shared platform origin. `null` when the organization has none — then every link falls back to the platform origin.
commsharbor_tracking_domain_create
Register the host that will serve this organization's message links. One per organization; registering never activates it. One per organization, and the host is unique across the platform — two tenants claiming the same name would make link routing ambiguous. Registering does not activate: publish the CNAME, then call `verify`.
commsharbor_tracking_domain_verify
Probe the host now and store what was seen. The ONLY way to reach `active`, and only after reaching this product on that host — DNS resolving is not enough. The only operation that can move a tracking domain to `active`, and it does so only after reaching this product's own health endpoint ON that host. A host that used to answer and stopped becomes `failed`, and links go back to the platform origin immediately.
commsharbor_tracking_domain_remove
Remove the tracking domain; NEW messages go back to the platform origin. Links already sent keep pointing at the removed host. Links already sent keep pointing at the removed host: this stops NEW messages, not old ones.
commsharbor_inboxes
List configured inbox addresses. Incoming mail is currently unavailable. Up to 100, newest first. A disabled address keeps its readable history. Incoming mail is currently unavailable.
commsharbor_inbox_create
Create an inbox address on a verified sending domain. An unverified domain returns 422. Incoming mail is currently unavailable; creation does not enable receipt. The domain must already be `verified` or `active`. Incoming mail is currently unavailable. Creating the address or changing mail records does not enable receipt.
commsharbor_inbox_get
Read one configured inbox address and its saved status. Incoming mail is currently unavailable. An active status does not prove receipt.
commsharbor_inbox_disable
Stop accepting mail at this address. History stays readable — this disables, it never erases. Disable the address and keep its stored history readable. Incoming mail is currently unavailable.
commsharbor_inbox_messages
List what arrived at one address, newest first. Summaries only, no body. Summaries only — no body. Read one message to get its text, HTML and headers.
commsharbor_inbox_message
Read one message: body, chosen headers and `auth`. `from` is text the sender chose; `auth` is the SPF/DKIM/DMARC verdict the receiving edge reached. Decide on `auth`. `auth` is what the receiving edge concluded about SPF, DKIM and DMARC. Treat `from` as text the sender chose: `auth` is the part that was checked.
commsharbor_inbox_attachment
Get a five-minute signed URL for one attachment, by its index in the message. Stored files have no automatic expiry. The download URL expires in five minutes. The stored attachment has no automatic expiry. Keep account credentials private when sharing the URL.
pricing
Current public prices and free allowances; no charge.