The Console API provides a way to interact with the features of the Console programmatically. It is also used to send emails.
To get started, create an API key from the Console. Note that the API key is project-specific, meaning it can only be used with the project it was created in.
https://relay.hyvor.com/api/console
application/json
(both for requests and responses)Authorization
header with your API key
as a Bearer token: Authorization: Bearer <your_api_key>
Scopes are used to control access to endpoints of the Console API. When creating an API key, you can select the scopes that the key will have access to. The available scopes are:
Each endpoint requires specific scopes to be included in the API key.
The Console API has rate limits to prevent abuse and ensure fair usage.
If you exceed these limits, you will receive a 429 Too Many Requests
response. The following standard headers are included in all API
responses to indicate the current rate limit status:
X-RateLimit-Limit
: The maximum number of requests allowed in the current time
window.X-RateLimit-Remaining
: The number of requests remaining in the current time
window.X-RateLimit-Reset
: How many seconds until the rate limit resets.Endpoints:
Objects:
POST /sends
(scope: sends.send)
Visit the Send Emails page for a detailed guide on how to send emails using this endpoint.
type Address = string | { email: string, name?: string };
type Request = {
from: Address,
to: Address | Address[],
cc?: Address | Address[],
bcc?: Address | Address[],
subject?: string,
body_html?: string,
body_text?: string,
headers?: Record<string, string>,
attachments?: Array<{
content: string, // base64 encoded
name?: string,
content_type?: string
}>
}
type Response = {
id: number,
message_id: string
}
GET /sends
(scope: sends.read)
type Request = {
limit?: number, // Optional. Default is 50
offset?: number, // Optional. Default is 0
status?: 'queued' | 'processing' | 'accepted' | 'bounced' | 'complained', // Optional. Filter by status
from_search?: string, // Optional. Search from address
to_search?: string // Optional. Search to address
}
type Response = Send[]
GET /sends/:id
(scope: sends.read)
type Request = {}
type Response = Send // includes attempts array
GET /sends/uuid/:uuid
(scope: sends.read)
type Request = {}
type Response = Send // includes attempts array
Endpoints:
Objects:
GET /domains
(scope: domains.read)
type Request = {
limit?: number, // Optional. Default is 50
offset?: number, // Optional. Default is 0
search?: string, // Optional. Search by domain name
}
type Response = Domain[]
POST /domains
(scope: domains.write)
type Request = {
domain: string
}
type Response = Domain
POST /domains/verify
(scope: domains.write)
type Request = {
// Either id or domain must be provided
id?: number,
domain?: string
}
type Response = Domain
GET /domains/by
(scope: domains.read)
type Request = {
// Either id or domain must be provided
id?: number,
domain?: string
}
type Response = Domain
type Request = {}
type Response = Domain
DELETE /domains
(scope: domains.write)
type Request = {
// Either id or domain must be provided
id?: number,
domain?: string
}
type Response = {}
Endpoints:
Objects:
GET /webhooks
type Request = {}
type Response = Webhook[]
POST /webhooks
See Webhooks page for available events.
type Request = {
url: string,
description: string,
events: string[]
}
type Response = Webhook
PATCH /webhooks/:id
type Request = {
url: string,
description: string,
events: string[]
}
type Response = Webhook
DELETE /webhooks/:id
type Request = {}
type Response = {}
GET /webhooks/deliveries
type Request = {
webhook_id?: number // Optional. Filter by webhook ID
}
type Response = WebhookDelivery[]
Endpoints:
Objects:
GET /api-keys
(scope: api_keys.read)
type Request = {}
type Response = ApiKey[]
POST /api-keys
(scope: api_keys.write)
Note: Maximum of 10 API keys are allowed per project.
type Request = {
name: string,
scopes: string[]
}
type Response = ApiKey // includes the raw key only on creation
PATCH /api-keys/:id
(scope: api_keys.write)
type Request = {
name?: string,
is_enabled?: boolean,
scopes?: string[]
}
type Response = ApiKey
DELETE /api-keys/:id
(scope: api_keys.write)
type Request = {}
type Response = {}
Endpoints:
Objects:
GET /suppressions
(scope: suppressions.read)
type Request = {
email?: string, // Optional. Search by email
reason?: 'bounce' | 'complaint' // Optional. Filter by reason
}
type Response = Suppression[]
DELETE /suppressions/:id
(scope: suppressions.write)
type Request = {}
type Response = {}
Endpoints:
GET /analytics/stats
(scope: analytics.read)
type Request = {}
type Response = {
sends_30d: number,
bounce_rate_30d: number,
complaint_rate_30d: number
}
GET /analytics/sends/chart
(scope: analytics.read)
type Request = {}
type Response = any // Chart data format
interface Send = {
id: number;
uuid: string;
created_at: number;
sent_at: number | null;
failed_at: number | null;
status: 'queued' | 'accepted' | 'bounced' | 'complained';
from_address: string;
to_address: string;
subject: string | null;
body_html: string | null;
body_text: string | null;
raw: string;
attempts: SendAttempt[];
}
interface SendRecipient {
id: number;
type: 'to' | 'cc' | 'bcc';
address: string;
name: string;
status: 'queued' | 'accepted' | 'retrying' | 'bounced' | 'complained' | 'failed';
accepted_at: number | null;
bounced_at: number | null;
failed_at: number | null;
}
interface SendAttempt {
id: number;
created_at: number;
status: 'accepted' | 'deferred' | 'bounced' | 'failed';
try_count: number;
resolved_mx_hosts: string[];
accepted_mx_host: string | null;
smtp_conversations: Record<string, any>;
error: string | null;
}
interface Bounce {
text: string;
status: string;
}
interface Complaint {
text: string;
feedback_type: string;
}
interface Domain {
id: number;
created_at: number;
domain: string;
status: 'pending' | 'active' | 'warning' | 'suspended';
dkim_selector: string;
dkim_host: string;
dkim_public_key: string;
dkim_txt_value: string;
dkim_checked_at: number | null;
dkim_error_message: string | null;
}
More about Domain Status.
interface Webhook {
id: number;
url: string;
description: string | null;
events: string[];
}
interface WebhookDelivery {
id: number;
created_at: number;
url: string;
event: string;
status: 'pending' | 'delivered' | 'failed';
response: string | null;
}
interface ApiKey {
id: number;
name: string;
scopes: string[];
key: string | null; // Only included when creating a new key
created_at: number;
is_enabled: boolean;
last_accessed_at: number | null;
}
interface Suppression {
id: number;
created_at: number;
email: string;
project: string;
reason: 'bounce' | 'complaint';
description: string | null;
}