Every API here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for apis
7 MCP tools reach this
find_apisBrowse and filter every API in the catalog.
get_api_artifactsOne API's artifacts, grouped by type.
get_openapiThe primary OpenAPI for this API.
find_similar_apisAPIs that look like this one.
apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
resolveTurn a domain, URL or GitHub org into the provider it belongs to.
find_cohortsEvery scored population of providers in the catalog.
All 92 tools →
Call it yourself
curl for this page
This API
curl "https://apis.io/api/v1/apis/honkio-ca:honkio-ca-email-domains-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"
Discovery needs no key. Ratings and market analysis are Pro.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we
store it to create your key and to recognise you if you sign in with another
provider. See our Privacy Policy and
Terms.
A second provider on the same verified email joins the account you already have.
openapi: 3.2.0
info:
title: HonkIO Email Domains API
description: 'Canadian-focused SMS gateway API.
## Canadian Compliance
- **CASL**: All commercial messages require consent. Use `/v1/compliance/consents` to record.
- **DNCL**: CRTC Do Not Call List checking is coming soon (not yet enforced).
- **PIPEDA / Quebec Law 25**: Data is stored in Canada (ca-central-1). Requests are processed in the United States in transit. Right-to-erasure available.
## Authentication
Provide your API key via `Authorization: Bearer mk_live_...` or `X-API-Key: mk_live_...`.
Test keys never send, never charge and can''t change live data; they work before your first top-up.
## Rate limits
100 requests per second per account. Every authenticated response carries `X-RateLimit-Limit`, `X-RateLimit-Remaining` and `X-RateLimit-Reset`.
## Pagination
Shape follows the route family, not one convention across the API: documented here rather than changed. Messages listings return `{ data, meta: { page, limit, total, pages } }`. Contacts, Contact Groups, Lists and Verify listings return `{ data, total, limit, offset }`. Compliance consent and opt-out listings accept `page`/`limit` and return `{ data }`, with no total. Account transactions use a cursor: pass `before`, get back `has_more`.'
version: 1.0.0
contact:
name: HonkIO Support
email: support@honkio.ca
servers:
- url: https://api.honkio.ca
description: Production
- url: http://localhost:3000
description: Local development
security:
- apiKey: []
- apiKeyHeader: []
tags:
- name: Email Domains
description: Verify sending domains for email
paths:
/v1/email-domains:
post:
summary: Add a sending domain
tags:
- Email Domains
description: Requires `email_domains:w`.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
domain:
type: string
minLength: 1
maxLength: 253
description: A domain or subdomain you control, such as mail.yourdomain.ca. Publish the DNS records the response lists, then verify it.
example: yourdomain.ca
required:
- domain
description: The domain to send from.
description: The domain to send from.
security:
- apiKey: []
- apiKeyHeader: []
x-honkio-permission: email_domains:w
responses:
'401':
description: Missing, invalid, revoked or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'402':
description: The account has no balance, or a LIVE key was used before the first top-up.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: The API key lacks the permission this operation requires, or the account is suspended or closed.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: 'Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
operationId: postV1EmailDomains
x-operation-id-source: derived
get:
summary: List sending domains
tags:
- Email Domains
description: Requires `email_domains:r`.
security:
- apiKey: []
- apiKeyHeader: []
x-honkio-permission: email_domains:r
responses:
'401':
description: Missing, invalid, revoked or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'402':
description: The account has no balance, or a LIVE key was used before the first top-up.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: The API key lacks the permission this operation requires, or the account is suspended or closed.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: 'Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
operationId: getV1EmailDomains
x-operation-id-source: derived
/v1/email-domains/{id}:
get:
summary: Get a sending domain
tags:
- Email Domains
description: Requires `email_domains:r`.
parameters:
- schema:
type: string
in: path
name: id
required: true
security:
- apiKey: []
- apiKeyHeader: []
x-honkio-permission: email_domains:r
responses:
'401':
description: Missing, invalid, revoked or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'402':
description: The account has no balance, or a LIVE key was used before the first top-up.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: The API key lacks the permission this operation requires, or the account is suspended or closed.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: 'Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
operationId: getV1EmailDomainsById
x-operation-id-source: derived
patch:
summary: Update a sending domain's open/click tracking or receiving
tags:
- Email Domains
description: Requires `email_domains:m`.
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
open_tracking:
type:
- boolean
- 'null'
description: Track opens on this domain's email. Null restores the platform default.
click_tracking:
type:
- boolean
- 'null'
description: Track clicks on this domain's email. Null restores the platform default.
receiving:
type: boolean
description: Receive email at this domain. The domain must be verified for sending first; the response adds the inbound MX record to publish.
description: 'The settings to change: at least one of open_tracking, click_tracking or receiving.'
description: 'The settings to change: at least one of open_tracking, click_tracking or receiving.'
parameters:
- schema:
type: string
in: path
name: id
required: true
security:
- apiKey: []
- apiKeyHeader: []
x-honkio-permission: email_domains:m
responses:
'200':
description: The updated domain, with the DNS records to publish (the inbound MX while receiving is on).
content:
application/json:
schema:
description: The updated domain, with the DNS records to publish (the inbound MX while receiving is on).
type: object
additionalProperties: true
required:
- id
- domain
- status
- region
- verified_at
- last_checked_at
- failure_reason
- revalidation_failed_at
- open_tracking
- click_tracking
- receiving_status
- receiving_requested_at
- receiving_verified_at
- receiving_failure_reason
- receiving_revalidation_failed_at
- receiving_last_checked_at
- receiving_warning
- created_at
- records
- receiving_missing
properties:
id:
type: string
domain:
type: string
status:
type: string
enum:
- pending
- verifying
- verified
- failed
- temporarily_failed
region:
type: string
verified_at:
type:
- string
- 'null'
format: date-time
last_checked_at:
type:
- string
- 'null'
format: date-time
failure_reason:
type:
- string
- 'null'
revalidation_failed_at:
type:
- string
- 'null'
format: date-time
open_tracking:
type:
- boolean
- 'null'
click_tracking:
type:
- boolean
- 'null'
receiving_status:
type: string
enum:
- 'off'
- pending
- verified
- failed
receiving_requested_at:
type:
- string
- 'null'
format: date-time
receiving_verified_at:
type:
- string
- 'null'
format: date-time
receiving_failure_reason:
type:
- string
- 'null'
receiving_revalidation_failed_at:
type:
- string
- 'null'
format: date-time
receiving_last_checked_at:
type:
- string
- 'null'
format: date-time
description: When the inbound MX was last checked on its own; last_checked_at dates the sending check.
receiving_warning:
type:
- string
- 'null'
enum:
- apex_mx
- null
description: 'apex_mx while receiving is on at a likely registrable apex: an MX there takes over the domain''s own mail.'
created_at:
type: string
format: date-time
records:
type: array
items:
type: object
additionalProperties: true
required:
- type
- name
- value
- purpose
properties:
type:
type: string
enum:
- TXT
- MX
name:
type: string
value:
type: string
purpose:
type: string
enum:
- dkim
- mail_from
- spf
- dmarc_recommended
- inbound
receiving_missing:
type: array
items:
type: object
additionalProperties: true
required:
- record
- expected
properties:
record:
type: string
expected:
type: string
description: 'The inbound MX, when this request just turned receiving on and it is not published yet; [] otherwise. A lookup only: POST /v1/email-domains/{id}/verify moves receiving_status.'
'401':
description: Missing, invalid, revoked or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'402':
description: The account has no balance, or a LIVE key was used before the first top-up.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: 'ACCOUNT_NOT_VERIFIED: turning receiving on for a live domain needs a verified owner mobile number. Turning receiving off, and every other field, is unaffected. Also FORBIDDEN when the key lacks the permission this operation requires, or the account is suspended or closed.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: 'NOT_FOUND: no such domain on this account. A test key finds test-mode domains only, so a live domain answers it the same way; a live key finds both.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: 'RECEIVING_REQUIRES_VERIFIED_DOMAIN: receiving can only be turned on for a domain verified for sending.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'422':
description: 'VALIDATION_ERROR: the request failed validation; details names the fields.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: 'Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
operationId: patchV1EmailDomainsById
x-operation-id-source: derived
delete:
summary: Delete a sending domain
tags:
- Email Domains
description: Requires `email_domains:d`.
parameters:
- schema:
type: string
in: path
name: id
required: true
security:
- apiKey: []
- apiKeyHeader: []
x-honkio-permission: email_domains:d
responses:
'204':
description: Deleted. Email from the domain stops until it is added and verified again.
'401':
description: Missing, invalid, revoked or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'402':
description: The account has no balance, or a LIVE key was used before the first top-up.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: The API key lacks the permission this operation requires, or the account is suspended or closed.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: 'NOT_FOUND: no such domain on this account. A test key finds test-mode domains only, so a live domain answers it the same way; a live key finds both.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'409':
description: 'EMAIL_DOMAIN_HAS_INFLIGHT: the domain still has queued, scheduled or sending emails.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: 'Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
operationId: deleteV1EmailDomainsById
x-operation-id-source: derived
/v1/email-domains/{id}/verify:
post:
summary: Re-check DNS and SES verification status
tags:
- Email Domains
description: Requires `email_domains:w`.
parameters:
- schema:
type: string
in: path
name: id
required: true
security:
- apiKey: []
- apiKeyHeader: []
x-honkio-permission: email_domains:w
responses:
'200':
description: The result of the check. missing lists sending records not found; receiving_missing the inbound MX when receiving is on and it is not published.
content:
application/json:
schema:
description: The result of the check. missing lists sending records not found; receiving_missing the inbound MX when receiving is on and it is not published.
type: object
additionalProperties: true
required:
- id
- status
- verified
- missing
- ses_status
- mail_from_status
- receiving_status
- receiving_missing
- receiving_warning
properties:
id:
type: string
status:
type: string
enum:
- pending
- verifying
- verified
- failed
- temporarily_failed
verified:
type: boolean
missing:
type: array
items:
type: object
additionalProperties: true
required:
- record
- expected
properties:
record:
type: string
expected:
type: string
ses_status:
type:
- string
- 'null'
mail_from_status:
type:
- string
- 'null'
receiving_status:
type: string
enum:
- 'off'
- pending
- verified
- failed
receiving_missing:
type: array
items:
type: object
additionalProperties: true
required:
- record
- expected
properties:
record:
type: string
expected:
type: string
receiving_warning:
type:
- string
- 'null'
enum:
- apex_mx
- null
description: 'apex_mx while receiving is on at a likely registrable apex: an MX there takes over the domain''s own mail.'
'401':
description: Missing, invalid, revoked or expired API key.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'402':
description: The account has no balance, or a LIVE key was used before the first top-up.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'403':
description: The API key lacks the permission this operation requires, or the account is suspended or closed.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'404':
description: 'NOT_FOUND: no such domain on this account. A test key finds test-mode domains only, so a live domain answers it the same way; a live key finds both.'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'429':
description: 'Rate limit reached: 100 requests per second per account, or a route-specific limit (Retry-After set where one applies).'
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: Unexpected server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
operationId: postV1EmailDomainsByIdVerify
x-operation-id-source: derived
components:
schemas:
Error:
type: object
description: Standard error body. The one visible exception is the OAuth 2.1 surface (/oauth/token, /oauth/register, /oauth/revoke), which follows RFC 6749/7591/7009 and answers { error, error_description } instead.
required:
- code
- message
- statusCode
properties:
code:
type: string
description: Machine-readable error code, e.g. VALIDATION_ERROR.
message:
type: string
description: Human-readable message in the request's locale (Accept-Language).
messageEn:
type: string
description: English message, always present alongside message.
messageFr:
type: string
description: French message, always present alongside message.
statusCode:
type: integer
description: The HTTP status, repeated in the body.
details:
description: 'Present on some errors: an AJV validation array, or error-specific structured detail.'
securitySchemes:
apiKey:
type: http
scheme: bearer
bearerFormat: API Key
description: Use `mk_live_...` for production or `mk_test_...` for testing.
apiKeyHeader:
type: apiKey
in: header
name: X-API-Key
description: 'Alternative to the Authorization header: send `mk_live_...` or `mk_test_...` as X-API-Key directly.'