Console API

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.

API Usage

  • API URL: https://relay.hyvor.com/api/console
  • Content-Type: application/json (both for requests and responses)
  • Authentication: Set the Authorization header with your API key as a Bearer token:
    Authorization: Bearer <your_api_key>

Scopes

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:

  • sends.read
  • sends.write
  • sends.send
  • domains.read
  • domains.write
  • webhooks.read
  • webhooks.write
  • api_keys.read
  • api_keys.write
  • suppressions.read
  • suppressions.write
  • analytics.read

Each endpoint requires specific scopes to be included in the API key.

Endpoints

Sends (Emails)

Endpoints:

Objects:

Send Email

POST /sends (scope: sends.send)

type Request = {
    from: string | { email: string, name?: string },
    to: string | { email: string, name?: string },
    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

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 Send

GET /sends/uuid/:uuid

type Request = {}
type Response = Send // includes attempts array

Domains

Endpoints:

Objects:

Get Domains

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[]

Create Domain

POST /domains (scope: domains.write)

type Request = {
    domain: string
}
type Response = Domain

Get Domain

GET /domains/:id (scope: domains.read)

type Request = {}
type Response = Domain

Delete Domain

DELETE /domains (scope: domains.write)

type Request = {
	// Either id or domain must be provided
	id?: number,
	domain?: string
}
type Response = {}

Webhooks

Endpoints:

Objects:

Get Webhooks

GET /webhooks

type Request = {}
type Response = Webhook[]

Create Webhook

POST /webhooks

type Request = {
    url: string,
    description: string,
    events: string[]
}
type Response = Webhook

Update Webhook

PATCH /webhooks/:id

type Request = {
    url: string,
    description: string,
    events: string[]
}
type Response = Webhook

Delete Webhook

DELETE /webhooks/:id

type Request = {}
type Response = {}

Get Webhook Deliveries

GET /webhooks/deliveries

type Request = {
    webhookId?: number // Optional. Filter by webhook ID
}
type Response = WebhookDelivery[]

API Keys

Endpoints:

Objects:

Get API Keys

GET /api-keys (scope: api_keys.read)

type Request = {}
type Response = ApiKey[]

Create API Key

POST /api-keys (scope: api_keys.write)

type Request = {
    name: string,
    scopes: string[]
}
type Response = ApiKey // includes the raw key only on creation

Update API Key

PATCH /api-keys/:id (scope: api_keys.write)

type Request = {
    name?: string,
    enabled?: boolean,
    scopes?: string[]
}
type Response = ApiKey

Delete API Key

DELETE /api-keys/:id (scope: api_keys.write)

type Request = {}
type Response = {}

Suppressions

Endpoints:

Objects:

Get Suppressions

GET /suppressions (scope: suppressions.read)

type Request = {
    email?: string, // Optional. Search by email
    reason?: 'bounce' | 'complaint' // Optional. Filter by reason
}
type Response = Suppression[]

Delete Suppression

DELETE /suppressions/:id (scope: suppressions.write)

type Request = {}
type Response = {}

Analytics

Endpoints:

Get Analytics Statistics

GET /analytics/stats (scope: analytics.read)

type Request = {}
type Response = {
    sends_30d: number,
    bounce_rate_30d: number,
    complaint_rate_30d: number
}

Get Analytics Chart Data

GET /analytics/sends/chart (scope: analytics.read)

type Request = {}
type Response = any // Chart data format

Objects

Send Object

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[];
}

SendAttempt Object

interface SendAttempt {
	id: number;
	created_at: number;
	status: 'accepted' | 'deferred' | 'bounced';
	try_count: number;
	resolved_mx_hosts: string[];
	accepted_mx_host: string | null;
	smtp_conversations: Record<string, any>;
	error: string | null;
}

Domain Object

interface Domain {
	id: number;
	created_at: number;
	domain: string;
	dkim_selector: string;
	dkim_host: string;
	dkim_txt_name: string;
	dkim_public_key: string;
	dkim_txt_value: string;
	dkim_verified: boolean;
	dkim_checked_at: number | null;
	dkim_error_message: string | null;
}

Webhook Object

interface Webhook {
	id: number;
	url: string;
	description: string;
	events: string[];
}

WebhookDelivery Object

interface WebhookDelivery {
	id: number;
	url: string;
	event: string;
	status: 'pending' | 'delivered' | 'failed';
	response: string;
	created_at: number;
}

ApiKey Object

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;
}

Suppression Object

interface Suppression {
	id: number;
	created_at: number;
	email: string;
	project: string;
	reason: 'bounce' | 'complaint';
	description: string | null;
}