Sell GreenmorMail to your own customers, from your own panel, on your own billing.
You keep the customer relationship, the login and the payment gateway. We run the mail infrastructure and invoice you wholesale, weekly. This API is how your systems create and manage mailboxes without anyone touching our dashboard.
https://api.greenmormail.com/api/v1
Create keys in your partner panel under Provisioning API. A key is displayed once.
curl https://api.greenmormail.com/api/v1/ping \
-H "Authorization: Bearer gmp_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Keys carry scopes and a mode:
| Mode | What it does |
|---|---|
test | Provisions for real, so you can build and run CI against it — but never creates a charge. |
live | Provisions and bills. |
test key first. Nothing you do with one will ever appear on an invoice.KEY="gmp_…"
API="https://api.greenmormail.com/api/v1"
# 1. the customer you are selling to
curl -s -X POST $API/customers -H "Authorization: Bearer $KEY" \
-H "Idempotency-Key: cust-1001" -H "Content-Type: application/json" \
-d '{"email":"owner@acme.com","name":"Acme Ltd","external_ref":"YOUR-CRM-1001"}'
# 2. their domain — the response carries the DNS records they must publish
curl -s -X POST $API/domains -H "Authorization: Bearer $KEY" \
-H "Idempotency-Key: dom-1001" -H "Content-Type: application/json" \
-d '{"domain":"acme.com","customer_id":247}'
# 3. once those records are live
curl -s -X POST $API/domains/acme.com/verify -H "Authorization: Bearer $KEY"
# 4. the mailbox
curl -s -X POST $API/mailboxes -H "Authorization: Bearer $KEY" \
-H "Idempotency-Key: mb-1001" -H "Content-Type: application/json" \
-d '{"domain":"acme.com","local_part":"sales","password":"…","external_ref":"YOUR-SEAT-55"}'
Put your own identifiers in external_ref on customers, domains and mailboxes. It
comes back on every read and on webhooks, so you never need a mapping table.
Every POST requires an Idempotency-Key. Retrying with the same key
returns the original response rather than provisioning twice — safe after a timeout, a redeploy or
a queue replay. Reusing a key with a different body is refused.
{ "error": { "code": "domain_not_verified", "message": "…", "field": "domain" } }
Branch on error.code. It is stable; the message is not.
| Code | Meaning |
|---|---|
domain_not_verified | Publish the DNS records, then call verify. |
email_already_registered | That address exists somewhere on the platform. Use a different contact address. |
domain_already_registered | Someone already holds that domain here. |
mailbox_exists | That address is already in use. |
seat_limit_reached | Your account's mailbox ceiling. Talk to us to raise it. |
account_write_blocked | Unpaid dues: provisioning is paused. Your customers' mail keeps flowing. |
insufficient_scope | The key lacks the scope for this call. |
rate_limited | Back off; see Retry-After. |
Your panel is the only interface your customer sees, so subscribe rather than poll. Register an
HTTPS endpoint and you receive domain.verified, mailbox.expiring,
mailbox.suspended and mailbox.quota_threshold.
Verify every delivery — the signature is an HMAC-SHA256 of the raw body, keyed by the secret shown when you registered the endpoint:
X-Greenmor-Signature: sha256=<hex>
Delivery is at-least-once with backoff, so deduplicate on event_id.
Mailboxes you create through this API are yours end to end. The platform sends
nothing to your customers — no renewal reminders, no expiry warnings, no deletion
notices. You hear about expiry through the mailbox.expiring webhook, and the wording
your customer receives is entirely yours.
| Calls | Limit |
|---|---|
| Reads | 600 / minute |
| Writes | 60 / minute |
| Domain verification | 10 / hour (it performs live DNS lookups) |
A throttled response is 429 with Retry-After and
X-RateLimit-*.
GET /ping tells you which region you are on, and every mailbox response
carries the IMAP, SMTP and webmail hosts your customers should actually use — they differ per
region, so never hard-code them.Don't build a panel. The GreenmorMail WHMCS module
wires ordering, suspension, upgrades and termination straight through to this API — one WHMCS
service is one mailbox. Drop it in modules/servers/, paste your key into the server's
Access Hash, and sell.
test key while you set the product up. You can
order, suspend and terminate for real without a single charge.The complete OpenAPI 3.1 specification: openapi.yaml. Load it into Postman, Insomnia, or a client generator.