Console API

The Console API allows you to automate your newsletter-related tasks over HTTP with API key authentication. This is the same API that we internally use at the Console.

Getting Started

  • Create a Console API key at Console → Settings → API Keys.
  • The base URL: https://post.hyvor.com/api/console
  • For each request, set Authorization header to Bearer <API_KEY>.
  • Available HTTP methods:
    • GET - Retrieve a resource
    • POST - Create a resource or perform an action
    • PUT - Update a resource
    • DELETE - Remove a resource
  • Request params can be set as JSON (recommended) or as application/x-www-form-urlencoded.
  • All endpoints return JSON data. The response will be an object or an array of objects.

In this documentation, all objects, request params, and responses are written as Typescript interfaces in order to make type declarations concise.

Categories

The Console API endpoints are categorized based on the resource they interact with.

Jump to each category:

Newsletter

Endpoints:

Objects:

Get newsletter data

GET /newsletter
type Request = {}
type Response = Newsletter

Update a newsletter

PATCH /newsletter
type Request = Partial<Newsletter>  // except id, created_at
type Response = Newsletter

Issue

Endpoints:

Objects:

Get issues

GET /issues
type Request = {
    limit?: number; // default: 50
    offset?: number; // default: 0
}
type Response = Issue[]

Create an issue

POST /issues
type Request = {}
type Response = Issue

Get an issue

GET /issues/{id}
type Request = {}
type Response = Issue

Update an issue

PATCH /issues/{id}
type Request = {
    subject?: string;
    lists?: number[];
    content?: string;
    sending_profile_id?: number;
}
type Response = Issue

Delete an issue

DELETE /issues/{id}
type Request = {}
type Response = {}

Send an issue

POST /issues/{id}/send
type Request = {}
type Response = Issue

Get issue sends

GET /issues/{id}/sends
type Request = {}
type Response = Send[]

Lists

Endpoints:

Objects:

Create a list

POST /lists
type Request = {
    name: string;   // max length: 255
    description?: string;
}
type Response = List

Update a list

PATCH /lists/{id}
type Request = {
    name?: string;   // max length: 255
    description?: string;
}
type Response = List

Delete a list

DELETE /lists/{id}
type Request = {}
type Response = {}

Subscriber

Endpoints:

Objects:

Get subscribers

GET /subscribers
type Request = {
    limit?: number; // default: 50
    offset?: number; // default: 0

    // filter by status
    status?: 'subscribed' | 'unsubscribed' | 'pending';
    
    // filter by list
    list_id?: number; 

    // search by email
    search?: string; 
}
type Response = Subscriber[]

Create a subscriber

POST /subscribers
type Request = {
    email: string;
    list_ids: number[];
    source?: 'console' | 'form' | 'import'; // default: 'console'
    subscribe_ip?: string | null;
    subscribed_at?: number | null; // unix timestamp
    unsubscribed_at?: number | null; // unix timestamp
}
type Response = Subscriber

Update a subscriber

PATCH /subscribers/{id}
type Request = {
    email?: string;
    list_ids?: number[];
    status?: 'subscribed' | 'unsubscribed' | 'pending';
    metadata?: Record<string, string>;
}
type Response = Subscriber

Delete a subscriber

DELETE /subscribers/{id}
type Request = {}
type Response = {}

Bulk update subscribers

POST /subscribers/bulk
type Request = {
    subscribers_ids: number[];
    action: 'delete' | 'status_change' | 'metadata_update';
    status?: 'subscribed' | 'unsubscribed' | 'pending'; // required if action is status_change
    metadata?: Record<string, string>; // required if action is metadata_update
}
type Response = {
    status: string;
    message: string;
    subscribers: Subscriber[];
}

Subscriber Metadata

Subscriber metadata definitions allow you to define custom fields for subscribers. These fields can be used to store additional information about subscribers.

Endpoints:

Objects:

Create a subscriber metadata definition

POST /subscriber-metadata-definitions
type Request = {
    key: string;   // max length: 255
    name: string;  // max length: 255
}
type Response = SubscriberMetadataDefinition
  • key can only contain lowercase letters, numbers, and underscores.
  • Once created, the key cannot be changed.

Update a subscriber metadata definition

PATCH /subscriber-metadata-definitions/{id}
type Request = {
    name: string;  // max length: 255
}
type Response = SubscriberMetadataDefinition

Delete a subscriber metadata definition

DELETE /subscriber-metadata-definitions/{id}
type Request = {}
type Response = {}

Sending Profile

Endpoints:

Objects:

Get sending profiles

GET /sending-profiles
type Request = {}
type Response = SendingProfile[]

Create a sending profile

POST /sending-profiles
type Request = {
    from_email: string;
    from_name?: string | null;
    reply_to_email?: string | null;
    brand_name?: string | null;
    brand_logo?: string | null; // a publicly accessible URL of the logo
    brand_url?: string | null;
}
type Response = SendingProfile

Update a sending profile

PATCH /sending-profiles/{id}
type Request = {
    from_email?: string;
    from_name?: string | null;
    reply_to_email?: string | null;
    brand_name?: string | null;
    brand_logo?: string | null; // a publicly accessible URL of the logo
    brand_url?: string | null;
    is_default?: true;
}
type Response = SendingProfile

Delete a sending profile

DELETE /sending-profiles/{id}
type Request = {}
type Response = {}

Template

Hyvor Post provides a flexible newsletter template system that allows you to customize the appearance of your newsletters.

Endpoints:

Objects:

Get newsletter template

GET /templates
type Request = {}
type Response = Template

Update newsletter template

PATCH /templates
type Request = {
    template?: string;
}
type Response = Template

Render newsletter template with content

POST /templates/render
type Request = {
    template?: string | null;
}
type Response = {
    html: string;
}

User

The owner of the newsletter can invite other users as Admins to collaborate on managing the newsletter.

Endpoints:

Objects:

Get user

GET /users
type Request = {}
type Response = User[]

Delete user

DELETE /users/{id}
type Request = {}
type Response = {}

Get invites

GET /invites
type Request = {}
type Response = UserInvite[]

Create an invite

POST /invites

You must ask your Admins to create a HYVOR account before sending an invitation.

type Request = {
    username?: string;
    email?: string;
}
type Response = UserInvite
  • Either username or email of the invitee's HYVOR account is required.

Delete an invite

DELETE /invites/{id}
type Request = {}
type Response = {}

Media

Endpoints:

Objects:

Upload media

POST /media
type Request = {
    // max size: 10MB
    // supported formats: jpg, jpeg, png, gif, webp
    file: File; 
    folder: 'issue_images' | 'newsletter_images';
}
type Response = Media

Export

Endpoints:

Objects:

Get subscriber exports

GET /export
type Request = {}
type Response = SubscriberExport[]

Create a subscriber export

POST /export
type Request = {}
type Response = SubscriberExport

Objects

Newsletter Object

interface Newsletter {
    id: string;
    subdomain: string;
    created_at: number; // unix timestamp
    name: string;

    address: string | null;
    unsubscribe_text: string | null;
    branding: boolean;

    template_color_accent: string | null;
    template_color_accent_text: string | null;
    template_color_background: string | null;
    template_color_background_text: string | null;
    template_color_box: string | null;
    template_color_box_text: string | null;

    template_box_shadow: string | null;
    template_box_radius: string | null;
    template_box_border: string | null;

    template_font_family: string | null;
    template_font_size: string | null;
    template_font_weight: string | null;
    template_font_weight_heading: string | null;
    template_font_line_height: string | null;

    form_title: string | null;
    form_description: string | null;
    form_footer_text: string | null;
    form_button_text: string | null;
    form_success_message: string | null;

    form_width: number | null;  // null = 100%
    form_custom_css: string | null;

    form_color_light_text: string | null; // null = inherit
    form_color_light_text_light: string | null;
    form_color_light_accent: string | null;
    form_color_light_accent_text: string | null;
    form_color_light_input: string | null;
    form_color_light_input_text: string | null;
    form_light_input_box_shadow: string | null;
    form_light_input_border: string | null;
    form_light_border_radius: number | null;

    form_color_dark_text: string | null; // null = inherit
    form_color_dark_text_light: string | null;
    form_color_dark_accent: string | null;
    form_color_dark_accent_text: string | null;
    form_color_dark_input: string | null;
    form_color_dark_input_text: string | null;
    form_dark_input_box_shadow: string | null;
    form_dark_input_border: string | null;
    form_dark_border_radius: number | null;

    form_default_color_palette: 'light' | 'dark' | 'os';
    form_input_border_radius: number;
}

Issue Object

interface Issue {
    id: number;
    uuid: string;
    created_at: number; // unix timestamp
    subject: string | null;
    content: string | null;
    sending_profile_id: number;
    status: 'draft' | 'scheduled' | 'sending' | 'sent';
    lists: number[];

    scheduled_at: number | null; // unix timestamp
    sending_at: number | null; // unix timestamp
    sent_at: number | null; // unix timestamp
    total_sends: number;

    from_email: string | null;
    from_name: string | null;
    reply_to_email: string | null;

    sendable_subscribers_count: number;
}

Send Object

interface Send {
    id: number;
    created_at: number; // unix timestamp
    subscriber: Subscriber | null;
    email: string;
    status: 'pending' | 'sent' | 'failed';

    sent_at: number | null; // unix timestamp
    failed_at: number | null; // unix timestamp
    delivered_at: number | null; // unix timestamp
    unsubscribed_at: number | null; // unix timestamp
    bounced_at: number | null; // unix timestamp
    hard_bounce: boolean;
    complained_at: number | null; // unix timestamp
}

List Object

interface List {
    id: number;
    created_at: number; // unix timestamp
    name: string;
    description: string | null;
    subscribers_count: number;
}

Subscriber Object

interface Subscriber {
    id: number;
    email: string;
    source: 'console' | 'form' | 'import';
    status: 'subscribed' | 'unsubscribed' | 'pending';
    list_ids: number[];
    subscribe_ip: string | null;
    is_opted_in: boolean;
    subscribed_at: number | null; // unix timestamp
    unsubscribed_at: number | null; // unix timestamp
    metadata: Record<string, string>;
}

Subscriber Metadata Definition Object

interface SubscriberMetadataDefinition {
    id: number;
    created_at: number; // unix timestamp
    key: string;
    name: string;
    type: 'text'; // only 'text' is currently supported
}

Sending Profile Object

interface SendingProfile {
    id: number;
    created_at: number; // unix timestamp
    from_email: string;
    from_name: string | null;
    reply_to_email: string | null;
    brand_name: string | null;
    brand_logo: string | null;
    brand_url: string | null;
    is_default: boolean;
    is_system: boolean;
}

Template Object

interface Template {
    template: string;
}

User Mini Object

interface UserMiniObject {
    name: string;
    email: string;
    username: string | null;
    picture_url: string | null;
}

User Object

interface User {
    id: number;
    role: 'owner' | 'admin';
    created_at: number; // unix timestamp
    user: UserMiniObject;
}

User Invite Object

interface UserInvite {
    id: number;
    created_at: number; // unix timestamp
    role: 'admin';
    user: UserMiniObject;
    expires_at: number; // unix timestamp
}

Media Object

interface Media {
    id: number;
    created_at: number; // unix timestamp
    folder: 'issue_images' | 'newsletter_images' | 'import' | 'export';
    url: string;
    size: number; // in bytes
    extension: string;
}

Subscriber Export Object

interface SubscriberExport {
    id: number;
    created_at: number; // unix timestamp
    status: 'pending' | 'completed' | 'failed';
    error_message: string | null;
    url: string | null;
}