API DOCS · V1

API reference

Every method, explained. Start with your key, configure SMTP, then connect your workflow.

START HERE

Your first integration

  1. Import the collection into Postman. Open its Variables tab and set baseUrl to this service’s HTTPS address.
  2. As admin, set adminApiKey and use Create a tenant. The response saves tenantId and tenantApiKey locally.
  3. Hand the tenant key to its owner securely. For tenant use, keep only the tenant key; never hand out a collection containing the admin key.
  4. Edit the collection SMTP variables and use Update your SMTP. Saving does not send.
  5. Preview a report, then explicitly execute a send request when ready.
Postman folders

Admin manages tenants and keys. Tenant configures SMTP and sends/previews reports. Public links opens documentation and health. Never share/export a collection containing real keys or passwords.

One header. Two privilege levels.

Every protected request uses the ApiKey header. Admin credentials work only on admin routes; tenant credentials work only on tenant, send and preview routes.

ApiKey: <admin-key>    # Admin methods only
ApiKey: <tenant-key>   # Tenant, send and preview methods only

Tenant keys contain at least 256 bits of random secret material. Only hashes are stored. The full key appears only in creation/regeneration responses; regenerating it immediately revokes the previous value. Disabling/deleting a tenant also blocks its key.

Tenant SMTP credentials are encrypted in PostgreSQL. Read operations return credential-presence information, never saved username/password. Use HTTPS and your automation’s secret store.

Errors, limits and delivery

StatusMeaningAction / detail
400Bad requestInvalid input, destination or deletion confirmation.
401UnauthorizedMissing, invalid, disabled or revoked key.
403ForbiddenValid key with the wrong privilege.
404Not foundAdmin target does not exist.
409Setup requiredMissing SMTP or undecryptable credentials.
413Payload too largeRequest body exceeds 1 MiB.
429Too many requests120 requests/minute per tenant; admin has a separate quota.
502SMTP failureDelivery may be uncertain.
504TimeoutSMTP exceeded a configured deadline; the response identifies the stage and log reference.
503UnavailableService/database configuration requires operator attention.
{
  "error": "A valid ApiKey header is required."
}

Messages allow 1–50 recipients. Structured reports allow 1–100 prospects. The service conceals recipient addresses from one another. Sender, recipients, subject, timestamps and final rendered HTML/plain-text bodies are retained in the tenant’s EmailLogs records. SMTP acceptance is recorded separately from uncertain or failed attempts; previews create no send log.

Acceptance is not delivery confirmation.

A successful response means SMTP accepted the message. A failure can occur after transmission starts. Check provider logs before retrying; the API has no automatic retries or deduplication.

POSTAdmin

Create a tenant and issue its first key

/api/admin/tenants

Create tenant metadata and a unique API key atomically. SMTP can be configured afterward.

Request fields

FieldRequirement / typeDescription
nameRequired1–200 characters, no control characters.
contactEmailOptionalBare email address; omit/null to clear.
isActiveOptionalDefaults to true; false blocks the tenant key.

JSON request

{
  "name": "Example automation",
  "contactEmail": "owner@example.com",
  "isActive": true
}

Example request

curl --fail-with-body -X POST "https://your-subdomain.example/api/admin/tenants" \
  -H "ApiKey: <admin-key>" \
  -H "Content-Type: application/json" \
  --data-binary @request.json

Response · HTTP 201

FieldTypeMeaning
tenantobjectTenant metadata as described below.
apiKeystringFull new key; returned once only.
notestringSave and securely hand off the key.
tenant.idUUIDTenant identifier.
tenant.namestringTenant display name.
tenant.contactEmailstring/nullOptional contact address.
tenant.isActivebooleanWhether the key is enabled.
tenant.createdAttimestampCreation time (UTC).
tenant.smtpConfiguredbooleanSMTP settings have been saved; does not test delivery.
tenant.keyIdentifierstringMasked identifier, not a usable key.
tenant.keyCreatedAttimestampCurrent key creation/rotation time.
{
  "tenant": {
    "id": "11111111-1111-4111-8111-111111111111",
    "name": "Example automation",
    "contactEmail": "owner@example.com",
    "isActive": true,
    "createdAt": "2026-10-07T12:00:00Z",
    "smtpConfigured": false,
    "keyIdentifier": "pmt_12345678…",
    "keyCreatedAt": "2026-10-07T12:00:00Z"
  },
  "apiKey": "pmt_<identifier>.<secret>",
  "note": "Save this key now and hand it to the tenant securely. It cannot be retrieved later."
}
Good to know

The full key is returned once. Save it securely and hand it to the tenant manually. An inactive tenant receives a key that cannot authenticate until reactivated.

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable.

GETAdmin

List tenants with pagination

/api/admin/tenants

List tenant metadata, masked key identifiers and SMTP setup state. No secrets are included.

Path and query parameters

FieldRequirement / typeDescription
pageOptional query integerDefault 1; range 1–1000000.
pageSizeOptional query integerDefault 50; range 1–100.

Example request

curl --fail-with-body -X GET "https://your-subdomain.example/api/admin/tenants" \
  -H "ApiKey: <admin-key>"

Response · HTTP 200

FieldTypeMeaning
itemsarrayTenant metadata objects.
pageintegerCurrent page.
pageSizeintegerCurrent page size.
totalintegerTotal tenants.
items[].idUUIDTenant identifier.
items[].namestringTenant display name.
items[].contactEmailstring/nullOptional contact address.
items[].isActivebooleanWhether the key is enabled.
items[].createdAttimestampCreation time (UTC).
items[].smtpConfiguredbooleanSMTP settings have been saved; does not test delivery.
items[].keyIdentifierstringMasked identifier, not a usable key.
items[].keyCreatedAttimestampCurrent key creation/rotation time.
{
  "items": [
    {
      "id": "11111111-1111-4111-8111-111111111111",
      "name": "Example automation",
      "contactEmail": "owner@example.com",
      "isActive": true,
      "createdAt": "2026-10-07T12:00:00Z",
      "smtpConfigured": false,
      "keyIdentifier": "pmt_12345678…",
      "keyCreatedAt": "2026-10-07T12:00:00Z"
    }
  ],
  "page": 1,
  "pageSize": 50,
  "total": 1
}

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable.

GETAdmin

Read a tenant

/api/admin/tenants/{tenantId}

Fetch metadata and setup state for one tenant.

Path and query parameters

FieldRequirement / typeDescription
tenantIdRequired path UUIDTarget tenant created by the admin.

Example request

curl --fail-with-body -X GET "https://your-subdomain.example/api/admin/tenants/<tenant-id>" \
  -H "ApiKey: <admin-key>"

Response · HTTP 200

FieldTypeMeaning
idUUIDTenant identifier.
namestringTenant display name.
contactEmailstring/nullOptional contact address.
isActivebooleanWhether the key is enabled.
createdAttimestampCreation time (UTC).
smtpConfiguredbooleanSMTP settings have been saved; does not test delivery.
keyIdentifierstringMasked identifier, not a usable key.
keyCreatedAttimestampCurrent key creation/rotation time.
{
  "id": "11111111-1111-4111-8111-111111111111",
  "name": "Example automation",
  "contactEmail": "owner@example.com",
  "isActive": true,
  "createdAt": "2026-10-07T12:00:00Z",
  "smtpConfigured": false,
  "keyIdentifier": "pmt_12345678…",
  "keyCreatedAt": "2026-10-07T12:00:00Z"
}

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable. 404 unknown tenant.

PUTAdmin

Update tenant metadata or active status

/api/admin/tenants/{tenantId}

Replace name, contact email and active status. SMTP settings and key are preserved.

Path and query parameters

FieldRequirement / typeDescription
tenantIdRequired path UUIDTarget tenant created by the admin.

Request fields

FieldRequirement / typeDescription
nameRequired1–200 characters, no control characters.
contactEmailOptionalBare email address; omit/null to clear.
isActiveOptionalDefaults to true; false blocks the tenant key.

JSON request

{
  "name": "Example automation",
  "contactEmail": "owner@example.com",
  "isActive": true
}

Example request

curl --fail-with-body -X PUT "https://your-subdomain.example/api/admin/tenants/<tenant-id>" \
  -H "ApiKey: <admin-key>" \
  -H "Content-Type: application/json" \
  --data-binary @request.json

Response · HTTP 200

FieldTypeMeaning
idUUIDTenant identifier.
namestringTenant display name.
contactEmailstring/nullOptional contact address.
isActivebooleanWhether the key is enabled.
createdAttimestampCreation time (UTC).
smtpConfiguredbooleanSMTP settings have been saved; does not test delivery.
keyIdentifierstringMasked identifier, not a usable key.
keyCreatedAttimestampCurrent key creation/rotation time.
{
  "id": "11111111-1111-4111-8111-111111111111",
  "name": "Example automation",
  "contactEmail": "owner@example.com",
  "isActive": true,
  "createdAt": "2026-10-07T12:00:00Z",
  "smtpConfigured": false,
  "keyIdentifier": "pmt_12345678…",
  "keyCreatedAt": "2026-10-07T12:00:00Z"
}
Good to know

Omitting isActive defaults to true. Set false to immediately disable the tenant key without deleting stored configuration. Omit/null contactEmail to clear it.

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable. 404 unknown tenant.

POSTAdmin

Regenerate a tenant API key

/api/admin/tenants/{tenantId}/api-key/regenerate

Atomically replace the tenant key and return its full new value.

Path and query parameters

FieldRequirement / typeDescription
tenantIdRequired path UUIDTarget tenant created by the admin.

Example request

curl --fail-with-body -X POST "https://your-subdomain.example/api/admin/tenants/<tenant-id>/api-key/regenerate" \
  -H "ApiKey: <admin-key>"

Response · HTTP 200

FieldTypeMeaning
tenantobjectTenant metadata as described below.
apiKeystringFull new key; returned once only.
notestringSave and securely hand off the key.
tenant.idUUIDTenant identifier.
tenant.namestringTenant display name.
tenant.contactEmailstring/nullOptional contact address.
tenant.isActivebooleanWhether the key is enabled.
tenant.createdAttimestampCreation time (UTC).
tenant.smtpConfiguredbooleanSMTP settings have been saved; does not test delivery.
tenant.keyIdentifierstringMasked identifier, not a usable key.
tenant.keyCreatedAttimestampCurrent key creation/rotation time.
{
  "tenant": {
    "id": "11111111-1111-4111-8111-111111111111",
    "name": "Example automation",
    "contactEmail": "owner@example.com",
    "isActive": true,
    "createdAt": "2026-10-07T12:00:00Z",
    "smtpConfigured": false,
    "keyIdentifier": "pmt_12345678…",
    "keyCreatedAt": "2026-10-07T12:00:00Z"
  },
  "apiKey": "pmt_<identifier>.<secret>",
  "note": "Save this key now and hand it to the tenant securely. It cannot be retrieved later."
}
Good to know

The old key stops working immediately. No overlap or automatic handoff. Save the new key and update the tenant automation secret. SMTP and metadata are unchanged.

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable. 404 unknown tenant.

GETAdmin

Read tenant SMTP settings

/api/admin/tenants/{tenantId}/smtp

Returns destination, sender and credential-presence information without revealing saved secrets.

Path and query parameters

FieldRequirement / typeDescription
tenantIdRequired path UUIDTarget tenant created by the admin.

Example request

curl --fail-with-body -X GET "https://your-subdomain.example/api/admin/tenants/<tenant-id>/smtp" \
  -H "ApiKey: <admin-key>"

Response · HTTP 200

FieldTypeMeaning
hoststringConfigured destination.
portintegerSMTP port.
securitystringTLS mode.
fromEmailstringSender email.
fromNamestringSender display name.
hasCredentialsbooleanEncrypted credentials exist; username/password/ciphertext are never returned.
{
  "host": "smtp.your-provider.example",
  "port": 587,
  "security": "StartTls",
  "fromEmail": "reports@example.com",
  "fromName": "Automation Reports",
  "hasCredentials": true
}
Good to know

Neither username, password nor encrypted credentials are returned. HTTP 409 means SMTP has not been configured.

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable. 404 unknown tenant. 409 missing/undecryptable SMTP configuration.

GETTenant

Read your SMTP settings

/api/tenant/smtp

Returns destination, sender and credential-presence information without revealing saved secrets.

Example request

curl --fail-with-body -X GET "https://your-subdomain.example/api/tenant/smtp" \
  -H "ApiKey: <tenant-key>"

Response · HTTP 200

FieldTypeMeaning
hoststringConfigured destination.
portintegerSMTP port.
securitystringTLS mode.
fromEmailstringSender email.
fromNamestringSender display name.
hasCredentialsbooleanEncrypted credentials exist; username/password/ciphertext are never returned.
{
  "host": "smtp.your-provider.example",
  "port": 587,
  "security": "StartTls",
  "fromEmail": "reports@example.com",
  "fromName": "Automation Reports",
  "hasCredentials": true
}
Good to know

Neither username, password nor encrypted credentials are returned. HTTP 409 means SMTP has not been configured.

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable. 409 missing/undecryptable SMTP configuration.

PUTAdmin

Update tenant SMTP settings

/api/admin/tenants/{tenantId}/smtp

Save SMTP destination, TLS mode, encrypted credentials and sender details. This operation sends no email.

Path and query parameters

FieldRequirement / typeDescription
tenantIdRequired path UUIDTarget tenant created by the admin.

Request fields

FieldRequirement / typeDescription
hostRequiredPublic SMTP hostname/address, maximum 253 characters.
portOptional1–65535; defaults to 587.
securityOptionalStartTls (default, usually port 587) or SslOnConnect (required for port 465). TLS is required in production.
usernameOptionalMaximum 1000 characters. Stored encrypted and never returned.
passwordOptional on editMaximum 1000 characters. Empty/omitted preserves saved password, including when username changes.
fromEmailRequiredProvider-authorized bare sender address.
fromNameOptionalSender name, maximum 200 characters; defaults to ProspectMailer.
clearCredentialsOptionalDefault false. True with empty username/password clears both for an authorized relay.

JSON request

{
  "host": "smtp.your-provider.example",
  "port": 587,
  "security": "StartTls",
  "username": "your-smtp-user",
  "password": "your-smtp-password",
  "fromEmail": "reports@example.com",
  "fromName": "Automation Reports",
  "clearCredentials": false
}

Example request

curl --fail-with-body -X PUT "https://your-subdomain.example/api/admin/tenants/<tenant-id>/smtp" \
  -H "ApiKey: <admin-key>" \
  -H "Content-Type: application/json" \
  --data-binary @request.json

Response · HTTP 200

FieldTypeMeaning
hoststringConfigured destination.
portintegerSMTP port.
securitystringTLS mode.
fromEmailstringSender email.
fromNamestringSender display name.
hasCredentialsbooleanEncrypted credentials exist; username/password/ciphertext are never returned.
{
  "host": "smtp.your-provider.example",
  "port": 587,
  "security": "StartTls",
  "fromEmail": "reports@example.com",
  "fromName": "Automation Reports",
  "hasCredentials": true
}
Good to know

Blank/omitted password preserves the old password, including when username changes. To clear credentials, set clearCredentials=true with empty username/password. Production permits only TLS and public destination addresses.

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable. 404 unknown tenant. 409 missing/undecryptable SMTP configuration.

PUTTenant

Update your SMTP settings

/api/tenant/smtp

Save SMTP destination, TLS mode, encrypted credentials and sender details. This operation sends no email.

Request fields

FieldRequirement / typeDescription
hostRequiredPublic SMTP hostname/address, maximum 253 characters.
portOptional1–65535; defaults to 587.
securityOptionalStartTls (default, usually port 587) or SslOnConnect (required for port 465). TLS is required in production.
usernameOptionalMaximum 1000 characters. Stored encrypted and never returned.
passwordOptional on editMaximum 1000 characters. Empty/omitted preserves saved password, including when username changes.
fromEmailRequiredProvider-authorized bare sender address.
fromNameOptionalSender name, maximum 200 characters; defaults to ProspectMailer.
clearCredentialsOptionalDefault false. True with empty username/password clears both for an authorized relay.

JSON request

{
  "host": "smtp.your-provider.example",
  "port": 587,
  "security": "StartTls",
  "username": "your-smtp-user",
  "password": "your-smtp-password",
  "fromEmail": "reports@example.com",
  "fromName": "Automation Reports",
  "clearCredentials": false
}

Example request

curl --fail-with-body -X PUT "https://your-subdomain.example/api/tenant/smtp" \
  -H "ApiKey: <tenant-key>" \
  -H "Content-Type: application/json" \
  --data-binary @request.json

Response · HTTP 200

FieldTypeMeaning
hoststringConfigured destination.
portintegerSMTP port.
securitystringTLS mode.
fromEmailstringSender email.
fromNamestringSender display name.
hasCredentialsbooleanEncrypted credentials exist; username/password/ciphertext are never returned.
{
  "host": "smtp.your-provider.example",
  "port": 587,
  "security": "StartTls",
  "fromEmail": "reports@example.com",
  "fromName": "Automation Reports",
  "hasCredentials": true
}
Good to know

Blank/omitted password preserves the old password, including when username changes. To clear credentials, set clearCredentials=true with empty username/password. Production permits only TLS and public destination addresses.

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable. 409 missing/undecryptable SMTP configuration.

DELETEAdmin

Permanently delete a tenant

/api/admin/tenants/{tenantId}

Delete the tenant and its SMTP/API-key records transactionally.

Path and query parameters

FieldRequirement / typeDescription
tenantIdRequired path UUIDTarget tenant created by the admin.
confirmTenantIdRequired query UUIDMust equal tenantId; confirms permanent deletion.

Example request

curl --fail-with-body -X DELETE "https://your-subdomain.example/api/admin/tenants/<tenant-id>?confirmTenantId=<tenant-id>" \
  -H "ApiKey: <admin-key>"

Response · HTTP 204

No response body.

Good to know

Destructive. Existing tenant keys stop working. Accepted/delivered messages cannot be recalled, and backups follow operator retention. No request body.

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable. 404 unknown tenant.

GETTenant

Read your tenant

/api/tenant

Return metadata and SMTP setup state for the tenant identified by your key. No target ID is accepted.

Example request

curl --fail-with-body -X GET "https://your-subdomain.example/api/tenant" \
  -H "ApiKey: <tenant-key>"

Response · HTTP 200

FieldTypeMeaning
idUUIDTenant identifier.
namestringTenant display name.
contactEmailstring/nullOptional contact address.
isActivebooleanWhether the key is enabled.
createdAttimestampCreation time (UTC).
smtpConfiguredbooleanSMTP settings have been saved; does not test delivery.
keyIdentifierstringMasked identifier, not a usable key.
keyCreatedAttimestampCurrent key creation/rotation time.
{
  "id": "11111111-1111-4111-8111-111111111111",
  "name": "Example automation",
  "contactEmail": "owner@example.com",
  "isActive": true,
  "createdAt": "2026-10-07T12:00:00Z",
  "smtpConfigured": false,
  "keyIdentifier": "pmt_12345678…",
  "keyCreatedAt": "2026-10-07T12:00:00Z"
}

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable.

POSTTenant

Send an HTML email

/api/emails/send

Wrap AI-supplied HTML in the navy-header email design and send through your tenant SMTP with a plain-text alternative.

Request fields

FieldRequirement / typeDescription
toRequired1–50 bare recipient email addresses.
subjectRequired1–200 characters; no control characters.
htmlBodyRequired1–500000 characters of AI HTML content. Wrapped in the navy-header design with inline styling; subject supplies the header title. Full HTML documents use their body content.
textBodyOptionalMaximum 500000 characters; absent/blank uses generic HTML-view instruction.

JSON request

{
  "to": [
    "recipient@example.com"
  ],
  "subject": "Your automation report",
  "htmlBody": "<h1>Automation report</h1><p>Your results are ready.</p>",
  "textBody": "Your results are ready."
}

Example request

curl --fail-with-body -X POST "https://your-subdomain.example/api/emails/send" \
  -H "ApiKey: <tenant-key>" \
  -H "Content-Type: application/json" \
  --data-binary @request.json

Response · HTTP 200

FieldTypeMeaning
statusstringaccepted means SMTP accepted the DATA transaction.
messageIdstringIdentifier for provider-log correlation.
notestringAcceptance is not confirmed inbox delivery.
{
  "status": "accepted",
  "messageId": "example-message-id@example.com",
  "note": "SMTP accepted the message; inbox delivery is not confirmed."
}
Good to know

Sends real email. Recipients are concealed from one another. The subject and body come from your AI workflow; the service supplies layout and default styling, not predefined report content. HTML is trusted caller content. Final bodies are stored in EmailLogs. Inspect provider logs before retrying an uncertain failure. SMTP must be configured first.

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable. 409 missing/undecryptable SMTP configuration. 502 SMTP failure; 504 timeout. Delivery may be uncertain; inspect provider logs before retrying.

POSTTenant

Render and send a prospect report

/api/prospects/send

Render a navy/teal HTML digest and complete plain-text alternative from structured prospects, then send through your tenant SMTP.

Request fields

FieldRequirement / typeDescription
toRequired1–50 bare recipient email addresses.
subjectRequired1–200 characters; no control characters.
titleOptionalMaximum 200 characters.
summaryOptionalMaximum 5000 characters.
reportDateOptionalYYYY-MM-DD; defaults to current UTC date.
prospectsRequired1–100 objects; companyName required; every field maximum 5000 characters.

Prospect fields

Each field allows at most 5000 characters. Text is escaped and links must use HTTP/HTTPS.

FieldRequirement / typeDescription
companyNameRequiredCompany name.
industryOptionalBusiness industry.
locationOptionalBusiness location.
websiteUrlOptionalHTTP/HTTPS company website.
ceoNameOptionalCEO/owner name.
ceoTitleOptionalActual leadership title.
ceoInfoOptionalProfessional background.
ceoEmailOptionalPublished executive business email; never guessed.
ceoSourceUrlOptionalHTTP/HTTPS leadership source.
generalEmailOptionalGeneral business email.
phoneOptionalBusiness phone.
contactUrlOptionalHTTP/HTTPS contact page.
needEvidenceOptionalEvidence of software need.
evidenceTypeOptionalCaller-provided confirmed/inferred classification.
evidenceUrlOptionalHTTP/HTTPS evidence source.
signalDateOptionalCaller-provided signal date text.
opportunityOptionalProposed solution.
budgetOptionalPublished budget or explicitly missing.
priorityOptionalCaller-assigned priority.

JSON request

{
  "to": [
    "recipient@example.com"
  ],
  "subject": "Business software opportunities",
  "title": "Your opportunity digest",
  "summary": "Example data supplied by your automation.",
  "reportDate": "2026-10-07",
  "prospects": [
    {
      "companyName": "Example Company (fictional)",
      "industry": "Wholesale",
      "websiteUrl": "https://example.com",
      "ceoName": "Example Owner",
      "ceoTitle": "Owner",
      "ceoInfo": "Example professional background.",
      "ceoEmail": "owner@example.com",
      "ceoSourceUrl": "https://example.com/team",
      "generalEmail": "hello@example.com",
      "phone": "+1 555 0100",
      "contactUrl": "https://example.com/contact",
      "needEvidence": "Example request for inventory integration.",
      "evidenceType": "Inferred",
      "evidenceUrl": "https://example.com/news",
      "signalDate": "2026-10-07",
      "opportunity": "Inventory portal",
      "budget": "Not published",
      "priority": "Medium",
      "location": "Example location"
    }
  ]
}

Example request

curl --fail-with-body -X POST "https://your-subdomain.example/api/prospects/send" \
  -H "ApiKey: <tenant-key>" \
  -H "Content-Type: application/json" \
  --data-binary @request.json

Response · HTTP 200

FieldTypeMeaning
statusstringaccepted means SMTP accepted the DATA transaction.
messageIdstringIdentifier for provider-log correlation.
notestringAcceptance is not confirmed inbox delivery.
{
  "status": "accepted",
  "messageId": "example-message-id@example.com",
  "note": "SMTP accepted the message; inbox delivery is not confirmed."
}
Good to know

Sends real email. Text is HTML-encoded and only HTTP/HTTPS links are clickable. Missing information is labeled; executive emails are never guessed. The caller verifies supplied facts. SMTP must be configured first.

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable. 409 missing/undecryptable SMTP configuration. 502 SMTP failure; 504 timeout. Delivery may be uncertain; inspect provider logs before retrying.

POSTTenant

Preview a report without sending

/api/prospects/preview

Render the same HTML digest returned by structured sending, without contacting SMTP.

Request fields

FieldRequirement / typeDescription
toRequired1–50 bare recipient email addresses.
subjectRequired1–200 characters; no control characters.
titleOptionalMaximum 200 characters.
summaryOptionalMaximum 5000 characters.
reportDateOptionalYYYY-MM-DD; defaults to current UTC date.
prospectsRequired1–100 objects; companyName required; every field maximum 5000 characters.

Prospect fields

Each field allows at most 5000 characters. Text is escaped and links must use HTTP/HTTPS.

FieldRequirement / typeDescription
companyNameRequiredCompany name.
industryOptionalBusiness industry.
locationOptionalBusiness location.
websiteUrlOptionalHTTP/HTTPS company website.
ceoNameOptionalCEO/owner name.
ceoTitleOptionalActual leadership title.
ceoInfoOptionalProfessional background.
ceoEmailOptionalPublished executive business email; never guessed.
ceoSourceUrlOptionalHTTP/HTTPS leadership source.
generalEmailOptionalGeneral business email.
phoneOptionalBusiness phone.
contactUrlOptionalHTTP/HTTPS contact page.
needEvidenceOptionalEvidence of software need.
evidenceTypeOptionalCaller-provided confirmed/inferred classification.
evidenceUrlOptionalHTTP/HTTPS evidence source.
signalDateOptionalCaller-provided signal date text.
opportunityOptionalProposed solution.
budgetOptionalPublished budget or explicitly missing.
priorityOptionalCaller-assigned priority.

JSON request

{
  "to": [
    "recipient@example.com"
  ],
  "subject": "Business software opportunities",
  "title": "Your opportunity digest",
  "summary": "Example data supplied by your automation.",
  "reportDate": "2026-10-07",
  "prospects": [
    {
      "companyName": "Example Company (fictional)",
      "industry": "Wholesale",
      "websiteUrl": "https://example.com",
      "ceoName": "Example Owner",
      "ceoTitle": "Owner",
      "ceoInfo": "Example professional background.",
      "ceoEmail": "owner@example.com",
      "ceoSourceUrl": "https://example.com/team",
      "generalEmail": "hello@example.com",
      "phone": "+1 555 0100",
      "contactUrl": "https://example.com/contact",
      "needEvidence": "Example request for inventory integration.",
      "evidenceType": "Inferred",
      "evidenceUrl": "https://example.com/news",
      "signalDate": "2026-10-07",
      "opportunity": "Inventory portal",
      "budget": "Not published",
      "priority": "Medium",
      "location": "Example location"
    }
  ]
}

Example request

curl --fail-with-body -X POST "https://your-subdomain.example/api/prospects/preview" \
  -H "ApiKey: <tenant-key>" \
  -H "Content-Type: application/json" \
  --data-binary @request.json

Response · HTTP 200

<!doctype html><html><body>Formatted prospect report...</body></html>
Good to know

Safe to preview. No email is sent and no SMTP configuration is required. Recipients and subject must still satisfy the sending validation. Response content type is text/html.

400 invalid input; 401 invalid/revoked key; 403 wrong credential privilege; 413 body over 1 MiB; 429 quota exceeded; 503 service/database unavailable.

GETPublic

Check process liveness

/health

Confirm that the API process is responding.

Example request

curl --fail-with-body -X GET "https://your-subdomain.example/health"

Response · HTTP 200

FieldTypeMeaning
statusstringok
checkstringliveness only
{
  "status": "ok",
  "check": "liveness only"
}
Good to know

No authentication. This does not test PostgreSQL, SMTP or inbox delivery.

This is liveness only; it does not verify PostgreSQL or SMTP.