Skip to main content
POST
/
marketplace
/
messaging
/
send-email
Send email
curl --request POST \
  --url http://api.gu1.ai/marketplace/messaging/send-email \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "to": "<string>",
  "fromEmail": "<string>",
  "fromSenderId": {},
  "templateParams": {},
  "templateId": {},
  "subject": "<string>",
  "htmlBody": "<string>",
  "textBody": "<string>"
}
'
Sends a single transactional email for the authenticated organization. Requires the Email marketplace integration and a configured messaging provider. See Messaging overview for prerequisites, billing, and senders.

Endpoint

POST https://api.gu1.ai/marketplace/messaging/send-email

Headers

Authorization: Bearer YOUR_API_KEY
Content-Type: application/json
X-Organization-ID: <uuid>   # optional; multi-org session users

Request body

Common

to
string
required
Recipient email address.
fromEmail
string
Full sender address (e.g. alerts@example.com). Must be a configured sender for the org; domain must be verified. Mutually exclusive with fromSenderId.
fromSenderId
string (UUID)
ID of a sender from Settings → Email → Senders. Mutually exclusive with fromEmail.
If you omit both fromEmail and fromSenderId, the platform uses the default sender configured for the messaging provider (environment on the server, typically MS_PROVIDER_FROM_EMAIL / MS_PROVIDER_FROM_NAME, with fallbacks such as SENDGRID_FROM_* or noreply@gueno.com + Güeno). That is not an error.
templateParams
object
Key-value map for {{placeholders}} in subject, htmlBody, textBody, or in a stored template. Values may be strings, numbers, or booleans (coerced for rendering). Default {}.

Mode A — Stored template

templateId
string (UUID)
required
ID of a message template with channel email (org or system template).
Do not send htmlBody or textBody in this mode.
subject
string
Optional fallback if the template has no subject or the subject is empty after placeholder replacement.

Mode B — Inline content

Do not send templateId.
subject
string
required
Email subject. May contain {{variables}} replaced via templateParams.
htmlBody
string
HTML body. Max ~500,000 characters. May include {{variables}}.
textBody
string
Plain-text body; used as multipart alternative when both HTML and text are sent, or converted to minimal HTML if HTML is omitted. Max ~500,000 characters. May include {{variables}}.
You must provide at least one of htmlBody or textBody.

Example — template

curl -X POST https://api.gu1.ai/marketplace/messaging/send-email \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "user@example.com",
    "templateId": "550e8400-e29b-41d4-a716-446655440000",
    "templateParams": { "name": "Ada", "token": "482910" },
    "fromEmail": "noreply@yourdomain.com"
  }'

Example — inline HTML + placeholders

curl -X POST https://api.gu1.ai/marketplace/messaging/send-email \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "user@example.com",
    "subject": "Your code: {{token}}",
    "htmlBody": "<p>Hello, your code is <strong>{{token}}</strong></p>",
    "templateParams": { "token": "482910" }
  }'

Example — plain text only

curl -X POST https://api.gu1.ai/marketplace/messaging/send-email \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "to": "user@example.com",
    "subject": "Notification",
    "textBody": "Line one\nLine two"
  }'

Success response

{
  "success": true,
  "messageId": "provider-message-id"
}
Exact fields may match your MessageDeliveryService / provider response.

Errors and HTTP status

Business and validation responses from this route use JSON like { "success": false, "error": "<English message>" } unless noted. All error strings are in English. Invalid JSON bodies may return a different shape from the validator (e.g. Zod field issues) at 400.
SituationTypical statusExample error (or note)
Email integration off for the org400Email integration is not active. Enable Email (global_sender_email) in Applications (Marketplace) for this organization.
Messaging provider URL not set (server)400MS_PROVIDER_URL is not configured on the server. Configure the messaging provider to send email.
Cost > 0 and no pack quota / credits400Insufficient balance for this send (cost … credits). Add tokens… (see response for full text)
Send succeeded but billing failed400Insufficient balance to record billing for this send. Current balance (…) is below required (…). …
Both templateId and inline body400 (validation)Use either templateId + templateParams, or htmlBody/textBody only — not both.
Neither template nor body400 (validation)Provide templateId or htmlBody/textBody.
Inline mode without subject400 (validation)subject is required when not using a template.
Template UUID wrong / other org404Template not found or not accessible for this organization.
Template exists but not email channel400Template channel is "<channel>"; email is required.
Template + empty subject after render400The template has no subject or it is empty after replacing variables. Send subject in the request body or set the subject on the template.
Both fromSenderId and fromEmail400Send only one of fromSenderId or fromEmail, not both.
Unknown fromSenderId400fromSenderId does not match a sender for this organization. Check Settings → Email → Senders.
fromEmail domain not in Güeno400Domain "…" is not registered in Güeno. Add and verify it under Settings → Email → Domains before using sender "…".
Domain not verified400Domain "…" is not verified yet. Complete DNS records and click Verify under Settings → Email → Domains.
Verified domain but sender row missing400Sender "…" is not configured. Add it under Settings → Email → Senders (domain "…" is already verified).
Empty inline subject after {{…}}400Subject is empty after replacing variables.
Empty body after render400htmlBody or textBody is empty after rendering.
No session org401{ "error": "Organization ID not found" } (no success field)
After validation, the MS Provider may still return { "success": false, "error": "…" } (e.g. provider rejection) at 200 or an error status depending on implementation—inspect success and error on every response.