In this documentation, all objects, request params, and responses are written as Typescript interfaces in order to make type declarations concise.
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.
https://post.hyvor.com/api/consoleAuthorization header to Bearer <API_KEY>.GET - Retrieve a resourcePOST - Create a resource or perform an actionPUT - Update a resourceDELETE - Remove a resourceJSON (recommended) or as application/x-www-form-urlencoded.In this documentation, all objects, request params, and responses are written as Typescript interfaces in order to make type declarations concise.
The Console API endpoints are categorized based on the resource they interact with.
Jump to each category:
Endpoints:
GET /newsletter - Get newsletter dataPATCH /newsletter - Update a newsletterObjects:
GET /newsletter type Request = {}
type Response = Newsletter PATCH /newsletter type Request = Partial<Newsletter> // except id, created_at
type Response = Newsletter Endpoints:
GET /issues - Get issuesPOST /issues - Create an issueGET /issues/{id} - Get an issuePATCH /issues/{id} - Update an issueDELETE /issues/{id} - Delete an issuePOST /issues/{id}/send - Send an issueGET /issues/{id}/sends - Get issue sendsObjects:
GET /issues type Request = {
limit?: number; // default: 50
offset?: number; // default: 0
}
type Response = Issue[] POST /issues type Request = {}
type Response = Issue GET /issues/{id} type Request = {}
type Response = Issue PATCH /issues/{id} type Request = {
subject?: string;
lists?: number[];
content?: string;
sending_profile_id?: number;
}
type Response = Issue DELETE /issues/{id} type Request = {}
type Response = {} POST /issues/{id}/send type Request = {}
type Response = Issue GET /issues/{id}/sends type Request = {}
type Response = Send[] Endpoints:
POST /lists - Create a listPATCH /lists/{id} - Update a listDELETE /lists/{id} - Delete a listObjects:
POST /lists type Request = {
name: string; // max length: 255
description?: string;
}
type Response = List PATCH /lists/{id} type Request = {
name?: string; // max length: 255
description?: string;
}
type Response = List DELETE /lists/{id} type Request = {}
type Response = {} Endpoints:
GET /subscribers - Get subscribersPOST /subscribers - Create a subscriberPATCH /subscribers/{id} - Update a subscriberDELETE /subscribers/{id} - Delete a subscriberPOST /subscribers/bulk - Bulk update subscribersObjects:
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[] 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 PATCH /subscribers/{id} type Request = {
email?: string;
list_ids?: number[];
status?: 'subscribed' | 'unsubscribed' | 'pending';
metadata?: Record<string, string>;
}
type Response = Subscriber DELETE /subscribers/{id} type Request = {}
type Response = {} 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 definitions allow you to define custom fields for subscribers. These fields can be used to store additional information about subscribers.
Endpoints:
POST /subscriber-metadata-definitions - Create a subscriber metadata definitionPATCH /subscriber-metadata-definitions/{id} - Update a subscriber metadata definitionDELETE /subscriber-metadata-definitions/{id} - Delete a subscriber metadata definitionObjects:
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.key cannot be changed.PATCH /subscriber-metadata-definitions/{id} type Request = {
name: string; // max length: 255
}
type Response = SubscriberMetadataDefinition DELETE /subscriber-metadata-definitions/{id} type Request = {}
type Response = {} Endpoints:
GET /sending-profiles - Get sending profilesPOST /sending-profiles - Create a sending
profilePATCH /sending-profiles/{id} - Update
a sending profileDELETE /sending-profiles/{id} - Delete
a sending profileObjects:
GET /sending-profiles type Request = {}
type Response = SendingProfile[] 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 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 /sending-profiles/{id} type Request = {}
type Response = {} Endpoints:
GET /templates - Get newsletter templatePATCH /templates - Update newsletter templatePOST /templates/render - Render newsletter template
with contentObjects:
GET /templates type Request = {}
type Response = Template PATCH /templates type Request = {
template?: string;
}
type Response = Template POST /templates/render type Request = {
template?: string | null;
}
type Response = {
html: string;
} The owner of the newsletter can invite other users as Admins to collaborate on managing the newsletter.
Endpoints:
GET /users - Get userDELETE /users/{id} - Delete userGET /invites - Get invitesPOST /invites - Create an inviteDELETE /invites/{id} - Delete an inviteObjects:
GET /users type Request = {}
type Response = User[] DELETE /users/{id} type Request = {}
type Response = {} GET /invites type Request = {}
type Response = UserInvite[] 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 username or email of the invitee's HYVOR account is required.DELETE /invites/{id} type Request = {}
type Response = {} Endpoints:
POST /media - Upload mediaObjects:
POST /media type Request = {
// max size: 10MB
// supported formats: jpg, jpeg, png, gif, webp
file: File;
folder: 'issue_images' | 'newsletter_images';
}
type Response = Media Endpoints:
GET /export - Get subscriber exportsPOST /export - Create a subscriber exportObjects:
GET /export type Request = {}
type Response = SubscriberExport[] POST /export type Request = {}
type Response = SubscriberExport 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;
} 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;
} 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
} interface List {
id: number;
created_at: number; // unix timestamp
name: string;
description: string | null;
subscribers_count: number;
} 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>;
} interface SubscriberMetadataDefinition {
id: number;
created_at: number; // unix timestamp
key: string;
name: string;
type: 'text'; // only 'text' is currently supported
} 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;
} interface Template {
template: string;
} interface UserMiniObject {
name: string;
email: string;
username: string | null;
picture_url: string | null;
} interface User {
id: number;
role: 'owner' | 'admin';
created_at: number; // unix timestamp
user: UserMiniObject;
} interface UserInvite {
id: number;
created_at: number; // unix timestamp
role: 'admin';
user: UserMiniObject;
expires_at: number; // unix timestamp
} interface Media {
id: number;
created_at: number; // unix timestamp
folder: 'issue_images' | 'newsletter_images' | 'import' | 'export';
url: string;
size: number; // in bytes
extension: string;
} interface SubscriberExport {
id: number;
created_at: number; // unix timestamp
status: 'pending' | 'completed' | 'failed';
error_message: string | null;
url: string | null;
}