FaxHub API (1.0.0)

Download OpenAPI specification:

SIA BMI Group — FaxHub: info@bmi.io URL: https://faxhub.us/developers/

PRE-LAUNCH: registration, payments, sending and receiving are NOT open. This is a preview contract. Do not collect credentials or documents, request login codes, or call transactional endpoints. Check https://faxhub.us/launch.json before any operation.

FaxHub API backed by the existing BMI ERP. Base URL: https://api.faxhub.us/v1. This dedicated contract is built and published by sites/faxhub.us only. The branded API hostname is planned; its production activation has not been verified.

After launch, sign in at https://app.faxhub.us using the existing ERP account system (service=faxhub). API keys use the existing ERP format: X-API-Key: <id>:<secret>. Key management requires a genuine customer cabinet Bearer session, not another API key. X-Account-Id selects an owned billing account returned by GET /accounts. Prefer an account-bound key. Existing ERP keys are not automatically fax-only or spend-limited.

PUT creates a fax draft; POST /faxes/{faxId}/send starts real transmission and billing. Use send_now=false when creating a draft. Never blindly repeat a write after a timeout. Currently billing occurs before transmission; automatic failure refunds are not implemented. Approved launch prices do not establish that backend billing has already been configured. Incoming-number purchase, inbound inbox, quotes, agent OAuth and new Stripe offers are not yet represented by implemented FaxHub-specific operations in this contract.

Faxes

Documents, outbound faxes, receipts and status webhooks

Загрузить вложение

Загрузка документа для факса (multipart/form-data, поле file). Файл конвертируется в fax-ready PDF (US Letter, 200 dpi, grayscale), считаются страницы, создаётся превью.

Поддерживаемые форматы: PDF, DOC, DOCX, JPG, PNG, TIFF, BMP, HEIC. Лимит размера — 50 МБ. Полученный id передаётся в file_ids при создании факса. Вложения, не привязанные к факсу в течение 24 часов, удаляются.

FaxHub gateway limit: the complete HTTP payload, including multipart overhead, must be below 10 MB. The ERP 50 MB limit above does not apply through API Gateway. Large-file direct uploads and asynchronous conversion must be implemented separately before advertising larger uploads.

Authorizations:
ApiKeyAuth
Request Body schema: multipart/form-data
required
file
required
string <binary>

Документ

enhance
boolean

Улучшение фото с камеры (выравнивание освещения); к документам не применять

Responses

Response samples

Content type
application/json
{}

Удалить вложение

Удаление загруженного вложения, ещё не привязанного к факсу

Authorizations:
ApiKeyAuth
path Parameters
fileId
required
string <uuid>

ID вложения (uuid)

Responses

Response samples

Content type
application/json
{
  • "error": false,
  • "message": "Operation completed successfully"
}

Адресная книга

Список контактов-получателей факсов

Authorizations:
ApiKeyAuth
query Parameters
q
string
Example: q=acme

Поиск по имени

page_num
integer
Example: page_num=1
page_size
integer
Example: page_size=50

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "navigation": {
    }
}

Добавить контакт

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
name
required
string
fax_number
required
string

Номер факса (7-15 цифр, любые разделители игнорируются)

company
string
phone_number
string
email
string
notes
string

Responses

Request samples

Content type
application/json
{
  • "name": "Acme Corp",
  • "fax_number": "+1 (877) 209-6018",
  • "company": "Acme Inc.",
  • "phone_number": "18775551234",
  • "email": "fax@acme.com",
  • "notes": "Main office fax"
}

Response samples

Content type
application/json
{
  • "id": 1,
  • "name": "Acme Corp",
  • "company": "Acme Inc.",
  • "fax_number": "18772096018",
  • "phone_number": "18775551234",
  • "email": "fax@acme.com",
  • "notes": "Main office fax"
}

Изменить контакт

Частичное обновление — передаются только изменяемые поля

Authorizations:
ApiKeyAuth
path Parameters
contactId
required
integer <int64>
Example: 1

ID контакта

Request Body schema: application/json
required
name
required
string
fax_number
required
string

Номер факса (7-15 цифр, любые разделители игнорируются)

company
string
phone_number
string
email
string
notes
string

Responses

Request samples

Content type
application/json
{
  • "name": "Acme Corp",
  • "fax_number": "+1 (877) 209-6018",
  • "company": "Acme Inc.",
  • "phone_number": "18775551234",
  • "email": "fax@acme.com",
  • "notes": "Main office fax"
}

Response samples

Content type
application/json
{
  • "id": 1,
  • "name": "Acme Corp",
  • "company": "Acme Inc.",
  • "fax_number": "18772096018",
  • "phone_number": "18775551234",
  • "email": "fax@acme.com",
  • "notes": "Main office fax"
}

Удалить контакт

Authorizations:
ApiKeyAuth
path Parameters
contactId
required
integer <int64>
Example: 1

ID контакта

Responses

Response samples

Content type
application/json
{
  • "error": false,
  • "message": "Operation completed successfully"
}

Шаблоны cover page

Список сохранённых шаблонов cover page клиента

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "navigation": {
    }
}

Добавить шаблон cover page

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
name
required
string
sender_name
required
string
contact_info
string
message
string
is_default
boolean

Responses

Request samples

Content type
application/json
{
  • "name": "Standard",
  • "sender_name": "John Smith",
  • "contact_info": "+1 877 209 6018",
  • "message": "Please find the documents attached.",
  • "is_default": true
}

Response samples

Content type
application/json
{
  • "id": 1,
  • "name": "Standard",
  • "sender_name": "John Smith",
  • "contact_info": "+1 877 209 6018",
  • "message": "Please find the documents attached.",
  • "is_default": true
}

Изменить шаблон cover page

Частичное обновление; is_default: true делает шаблон дефолтным (снимая флаг с остальных)

Authorizations:
ApiKeyAuth
path Parameters
templateId
required
integer <int64>
Example: 1

ID шаблона

Request Body schema: application/json
required
name
required
string
sender_name
required
string
contact_info
string
message
string
is_default
boolean

Responses

Request samples

Content type
application/json
{
  • "name": "Standard",
  • "sender_name": "John Smith",
  • "contact_info": "+1 877 209 6018",
  • "message": "Please find the documents attached.",
  • "is_default": true
}

Response samples

Content type
application/json
{
  • "id": 1,
  • "name": "Standard",
  • "sender_name": "John Smith",
  • "contact_info": "+1 877 209 6018",
  • "message": "Please find the documents attached.",
  • "is_default": true
}

Удалить шаблон cover page

Authorizations:
ApiKeyAuth
path Parameters
templateId
required
integer <int64>
Example: 1

ID шаблона

Responses

Response samples

Content type
application/json
{
  • "error": false,
  • "message": "Operation completed successfully"
}

Список webhooks

Webhooks клиента для событий статусов факсов (secret не возвращается)

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "navigation": {
    }
}

Добавить webhook

Регистрация URL для событий факсов. Ответ содержит secret — он показывается ЕДИНСТВЕННЫЙ раз, сохраните его. Доставка подписывается заголовком X-FaxHub-Signature: sha256=<HMAC-SHA256(body, secret)>; событие — в X-FaxHub-Event. После 10 неудачных доставок подряд webhook отключается автоматически.

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
url
string

HTTPS URL доставки (обязателен при создании)

events
Array of strings
Items Enum: "fax.sent" "fax.error"

События подписки (обязательны при создании)

is_active
boolean

Включить/выключить (только для обновления)

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "id": 1,
  • "events": [
    ],
  • "is_active": true,
  • "last_status": "http 200",
  • "last_sent_at": "2026-07-03T10:00:00Z",
  • "secret": "whsec_1a2b3c..."
}

Изменить webhook

Частичное обновление url/events/is_active; включение сбрасывает счётчик неудач

Authorizations:
ApiKeyAuth
path Parameters
webhookId
required
integer <int64>
Example: 1

ID webhook

Request Body schema: application/json
required
url
string

HTTPS URL доставки (обязателен при создании)

events
Array of strings
Items Enum: "fax.sent" "fax.error"

События подписки (обязательны при создании)

is_active
boolean

Включить/выключить (только для обновления)

Responses

Request samples

Content type
application/json
{}

Response samples

Content type
application/json
{
  • "id": 1,
  • "events": [
    ],
  • "is_active": true,
  • "last_status": "http 200",
  • "last_sent_at": "2026-07-03T10:00:00Z",
  • "secret": "whsec_1a2b3c..."
}

Удалить webhook

Authorizations:
ApiKeyAuth
path Parameters
webhookId
required
integer <int64>
Example: 1

ID webhook

Responses

Response samples

Content type
application/json
{
  • "error": false,
  • "message": "Operation completed successfully"
}

Тестовая доставка webhook

Синхронно отправляет тестовое событие webhook.test на URL и возвращает результат

Authorizations:
ApiKeyAuth
path Parameters
webhookId
required
integer <int64>
Example: 1

ID webhook

Responses

Response samples

Content type
application/json
{
  • "error": false,
  • "delivered": true,
  • "status": "http 200"
}

Сменить секрет webhook

Генерирует новый секрет подписи; старый перестаёт действовать немедленно. Ответ содержит новый secret (единственный показ).

Authorizations:
ApiKeyAuth
path Parameters
webhookId
required
integer <int64>
Example: 1

ID webhook

Responses

Response samples

Content type
application/json
{
  • "id": 1,
  • "events": [
    ],
  • "is_active": true,
  • "last_status": "http 200",
  • "last_sent_at": "2026-07-03T10:00:00Z",
  • "secret": "whsec_1a2b3c..."
}

Расход страниц за месяц

Списанные страницы факсов с начала календарного месяца (UTC)

Authorizations:
ApiKeyAuth

Responses

Response samples

Content type
application/json
{
  • "month": "2026-07",
  • "billed_pages": 42,
  • "included_pages": null
}

Проверить подлинность квитанции

Публичная проверка подлинности квитанции — этот URL зашит в QR-код на PDF-квитанции. Авторизация не требуется; вместо неё обязателен подписанный параметр key. Подтверждает только факт отправки: в fax пустые file_url и preview_url, cover_page = null.

path Parameters
faxId
required
string <uuid>

ID факса (uuid)

query Parameters
key
required
string

Подпись из QR-кода

Responses

Response samples

Content type
application/json
{}

Список факсов

Список факсов клиента за период + агрегированная статистика

Authorizations:
ApiKeyAuth
query Parameters
date_from
string <date>
Example: date_from=2026-07-01

Период от (включительно). По умолчанию — 30 дней назад

date_to
string <date>
Example: date_to=2026-07-31

Период до (включительно). По умолчанию — сегодня

status
string
Enum: "new" "queued" "in_progress" "sent" "error"
Example: status=sent

Фильтр по статусу

to_number
string
Example: to_number=+18772096018

Фильтр по номеру получателя

page_num
integer
Example: page_num=1

Номер страницы

page_size
integer
Example: page_size=50

Количество элементов на странице

Responses

Response samples

Content type
application/json
{
  • "statistics": {
    },
  • "data": [],
  • "navigation": {
    }
}

Создать факс

Создание факса-черновика из загруженных вложений (POST /faxes/files). С send_now: true факс сразу ставится в очередь отправки (требуется положительный баланс).

Authorizations:
ApiKeyAuth
Request Body schema: application/json
required
to_number
required
string

Номер факса получателя (E.164). В v1 доступны только США и Канада (NANP, код страны 1) — номер другого направления отклоняется с ошибкой ещё при создании факса.

file_ids
required
Array of strings <uuid> [ items <uuid > ]

ID загруженных вложений (POST /faxes/files) в порядке склейки

object (FaxCoverPage)
cover_template_id
integer

ID шаблона cover page (альтернатива cover_page; поля cover_page перекрывают шаблон)

scheduled_at
string <date-time>

Отложенная отправка (UTC, будущее время); отправится после вызова send

send_now
boolean

true — сразу поставить в очередь отправки (эквивалент POST /faxes/{faxId}/send)

Responses

Request samples

Content type
application/json
{
  • "to_number": "+18772096018",
  • "file_ids": [
    ],
  • "cover_page": {
    },
  • "cover_template_id": 1,
  • "scheduled_at": "2026-07-04T09:00:00Z",
  • "send_now": false
}

Response samples

Content type
application/json
{}

Получить факс

Данные факса по его ID

Authorizations:
ApiKeyAuth
path Parameters
faxId
required
string <uuid>
Example: f47ac10b-58cc-4372-a567-0e02b2c3d479

ID факса (uuid)

Responses

Response samples

Content type
application/json
{}

Удалить факс

Удаление факса. Факс в очереди или в процессе передачи удалить нельзя — сначала cancel.

Authorizations:
ApiKeyAuth
path Parameters
faxId
required
string <uuid>

ID факса (uuid)

Responses

Response samples

Content type
application/json
{
  • "error": false,
  • "message": "Operation completed successfully"
}

Отправить факс

Постановка факса в очередь отправки. Требуется положительный баланс лицевого счёта. Отправить можно факс в статусе new или error (повторная отправка после ошибки). Страницы факса тарифицируются по тарифному плану (1 страница = 1 минута).

Authorizations:
ApiKeyAuth
path Parameters
faxId
required
string <uuid>

ID факса (uuid)

Responses

Response samples

Content type
application/json
{}

Отменить отправку

Отмена запрошенной/запланированной отправки: queued → new (черновик сохраняется). Факс, уже переданный в шлюз (in_progress), отменить нельзя.

Authorizations:
ApiKeyAuth
path Parameters
faxId
required
string <uuid>

ID факса (uuid)

Responses

Response samples

Content type
application/json
{}

Дублировать факс

Создание черновика-копии факса (те же вложения, получатель и cover page)

Authorizations:
ApiKeyAuth
path Parameters
faxId
required
string <uuid>

ID факса для дублирования (uuid)

Responses

Response samples

Content type
application/json
{}

Получить cover page факса

Ссылка на PDF cover page (генерируется при первом обращении)

Authorizations:
ApiKeyAuth
path Parameters
faxId
required
string <uuid>

ID факса (uuid)

Responses

Response samples

Content type
application/json

Задать / убрать cover page

Установка или обновление cover page черновика (status new/error). Пустое тело {} — убрать cover page. Страницы факса пересчитываются.

Authorizations:
ApiKeyAuth
path Parameters
faxId
required
string <uuid>

ID факса (uuid)

Request Body schema: application/json
required
sender_name
required
string

Имя отправителя

contact_info
string

Контактные данные отправителя

message
string

Сопроводительный текст

Responses

Request samples

Content type
application/json
{
  • "sender_name": "John Smith",
  • "contact_info": "+1 877 209 6018, john@example.com",
  • "message": "Please find the contract documents attached."
}

Response samples

Content type
application/json
{}

Квитанция факса

PDF «Fax Confirmation Report» с параметрами передачи и QR-кодом публичной проверки подлинности. Доступна после финального статуса (sent/error); генерируется при первом обращении.

Authorizations:
ApiKeyAuth
path Parameters
faxId
required
string <uuid>

ID факса (uuid)

Responses

Response samples

Accounts

Existing ERP customer billing accounts

Список лицевых счетов

Получение списка лицевых счетов клиента. Закрытые лицевые счета не возвращаются, если у клиента есть хотя бы один незакрытый; если незакрытых нет (например, единственный счёт закрыт) — возвращаются все счета клиента. Закрытый счёт по-прежнему доступен по GET /accounts/{accountId} и через заголовок X-Account-Id.

Authorizations:
ApiKeyAuth
query Parameters
page_num
integer
Example: page_num=1

Номер страницы

page_size
integer
Example: page_size=50

Количество элементов на странице

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "navigation": {
    }
}

Получить данные лицевого счёта

Возвращает данные лицевого счёта по его ID

Authorizations:
ApiKeyAuth
path Parameters
accountId
required
integer <int64>
Example: 137154

ID лицевого счёта

Responses

Response samples

Content type
application/json
{
  • "id": 137154,
  • "status": "active",
  • "name": "Основной",
  • "id_customer": 3001,
  • "currency": {
    },
  • "monthly_fee": 150,
  • "balance_opening": 1351,
  • "income": 500,
  • "expense": 350.5,
  • "balance": 1500.5,
  • "limit": -5000,
  • "remainder": 6500.5,
  • "provider": {
    }
}

Cabinet API Keys

Existing ERP API-key lifecycle; interactive cabinet Bearer session required

Список API-ключей

Активные и просроченные ключи клиента (отозванные не показываются). Секрет всегда маскирован — полное значение доступно только у одного ключа через ?reveal=1.

Ключами управляют только из интерактивной сессии ЛК (Authorization: Bearer): запрос с X-API-Key (любым, в том числе действующим) отклоняется 403, в режиме менеджерского входа под клиентом — тоже 403.

Authorizations:
BearerAuth
query Parameters
page_num
integer
Example: page_num=1

Номер страницы

page_size
integer
Example: page_size=50

Количество элементов на странице (2..200)

Responses

Response samples

Content type
application/json
{
  • "data": [
    ],
  • "navigation": {
    }
}

Выпустить API-ключ

Самообслуживание: клиент выпускает себе ключ (бессрочный). Ответ содержит полное значение api_key — единственный момент, когда его отдают без ?reveal=1. Больше 10 активных ключей на клиента не выпускается — сначала отзовите неиспользуемые.

Только из сессии ЛК (Authorization: Bearer), не в менеджерском входе. Выпуск пишется в журнал авторизации клиента (событие apikey_created: учётка, сессия, IP, маска ключа).

Authorizations:
BearerAuth
Request Body schema: application/json
optional
account_bound
boolean
Default: false

true — привязать ключ к эффективному лицевому счёту запроса (модель интеграций: заголовок X-Account-Id в дальнейшем игнорируется). false/отсутствует — ключ клиентского масштаба, лицевой счёт выбирается заголовком при каждом запросе.

Responses

Request samples

Content type
application/json
{
  • "account_bound": true
}

Response samples

Content type
application/json
{
  • "id": 42,
  • "key_masked": "42:Xq7L••••••••bX9",
  • "api_key": "42:Xq7Lm2Rz9TbV4kPw8NcY3dHf6GsJ1aEuQ5oZbX9",
  • "account_id": 100001,
  • "active": true,
  • "created_at": "2026-08-21T09:15:00Z",
  • "last_used_at": "2026-08-21T14:02:11Z",
  • "expires_at": null
}

Получить API-ключ

Один ключ клиента. По умолчанию секрет маскирован; reveal=1 возвращает полное значение в поле api_key (кнопка «Показать» в ЛК — секрет хранится обратимо, поэтому доступен и после создания). Чужой или отозванный ключ — 404.

Только из сессии ЛК (Authorization: Bearer), не в менеджерском входе. Раскрытие (reveal=1) пишется в журнал авторизации клиента (событие apikey_revealed: учётка, сессия, IP, маска ключа).

Authorizations:
BearerAuth
path Parameters
keyId
required
integer
Example: 42

ID ключа

query Parameters
reveal
integer
Enum: 0 1
Example: reveal=1

1 — вернуть полное значение ключа в поле api_key

Responses

Response samples

Content type
application/json
{
  • "id": 42,
  • "key_masked": "42:Xq7L••••••••bX9",
  • "api_key": "42:Xq7Lm2Rz9TbV4kPw8NcY3dHf6GsJ1aEuQ5oZbX9",
  • "account_id": 100001,
  • "active": true,
  • "created_at": "2026-08-21T09:15:00Z",
  • "last_used_at": "2026-08-21T14:02:11Z",
  • "expires_at": null
}

Отозвать API-ключ

Ключ немедленно перестаёт авторизовывать запросы и пропадает из списка. Действие необратимо — восстановить отозванный ключ нельзя, нужно выпустить новый. Отзыв, как выпуск и раскрытие, фиксируется в журнале доступа клиента (видно менеджеру в карточке клиента).

Только из сессии ЛК (Authorization: Bearer), не в менеджерском входе.

Authorizations:
BearerAuth
path Parameters
keyId
required
integer
Example: 42

ID ключа

Responses

Response samples

Content type
application/json
{
  • "error": false,
  • "message": "Operation completed successfully"
}