Справочник эндпоинтов
Эндпоинты участника доступны под префиксом /api/v1/public/ на https://api.vibevo.io и требуют API-ключ с нужным скоупом. Два гостевых GET каталога креаторов под /api/v1/ не требуют API-ключа и описаны ниже.
Каталог креаторов и размещения
Гостевое чтение отделено от защищённых операций участника. В URL ниже пути указаны относительно https://api.vibevo.io/api/v1.
Гостевой каталог
GET /creator-catalog принимает q, channelType (STREAMER или SOCIAL), platform, format, topic, language, geo, audienceGeo, minPriceCents, maxPriceCents, availability, sort (price, relevance, activity), limit (1–100) и cursor. audienceGeo — ISO-код страны из текущего проверенного распределения аудитории с положительной долей; lowercase нормализуется в uppercase. Старый geo остаётся тегом географии профиля. platform и audienceGeo должны совпасть с одной активной опубликованной услугой канала. Сортировка price и её cursor используют минимальную опубликованную цену автора, которая может отличаться от услуги, подобранной фильтрами. Единственное допустимое значение availability — AVAILABLE; фильтр учитывает опубликованные услуги. Даты заказа и «по договорённости» фильтром не являются.
curl 'https://api.vibevo.io/api/v1/creator-catalog?channelType=STREAMER&availability=AVAILABLE&limit=20'
# Anonymous response (public fields only)
{
"data": [{
"publicId": "d8e805e4-1ec5-4ab6-a734-4ea389cecc6c",
"metricsObservationId": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"lastModified": "2026-10-08T12:00:00.000Z",
"displayName": "Streamer One",
"topics": ["gaming"],
"languages": ["en"],
"channelType": "STREAMER",
"channels": [{"platform":"TWITCH","handle":"streamer_one","canonicalUrl":"https://www.twitch.tv/streamer_one"}],
"services": [{
"serviceListingId": 7, "type": "STREAM", "variant": "MENTION",
"channel":{"platform":"TWITCH","handle":"streamer_one","canonicalUrl":"https://www.twitch.tv/streamer_one"},
"proofModes":["PUBLIC_VOD"],
"title": "Product mention", "unit": "broadcast",
"basePrice": {"raw":"100000000","currency":"USDT","decimals":6},
"packageOptions": [{"quantity":1,"discountBps":0,"packageBase":{"raw":"100000000","currency":"USDT","decimals":6}},{"quantity":5,"discountBps":500,"packageBase":{"raw":"475000000","currency":"USDT","decimals":6}}]
}],
"metrics": []
}],
"nextCursor": null
}GET /creator-pages/{publicId} отдаёт страницу, пока креатор её опубликовал и у неё есть доступные услуги с условиями использования. Иначе API отвечает 404 с кодом RESOURCE_NOT_FOUND. Предварительная модерация профиля, цен, услуг и ручной ссылки не требуется. Черновики, контакты, файлы подтверждений, расписание и комиссионные поля не выдаются. Отзыв публикации обновляет доступность страницы, HTML, Open Graph, кэш и sitemap; неопубликованные страницы не индексируются.
Публичный ответ и цены
В каталоге указывается опубликованная базовая цена услуги без комиссий и дохода креатора. Денежное значение имеет вид {raw, currency: "USDT", decimals: 6}; raw — целое число в микросуммах USDT. Например, raw "100000000" означает 100 USDT. В запросе priceCents передаётся целая строка центов; ввод цены в USDT допускает максимум два знака после запятой.
Для подключённого верифицированного соцаккаунта channels[].audience может содержать проверенную географию, возраст и пол именно этого аккаунта: source, capturedAt, verifiedAt, periodDays, geo и demo. Средние просмотры считаются по известным неотрицательным просмотрам последних пяти публичных публикаций. Для ручных каналов доверенных статистических показателей нет; отсутствие данных не заменяется нулём. Приватные snapshot/evidence/connection IDs не возвращаются.
Защищённый поток участника
Все пути в этом списке имеют префикс /public и требуют API-ключа: GET-запросы — read, мутации — write плюс актуальные роль и права объекта.
- Креатор: GET/PATCH /public/influencer-profile; GET /public/influencer-profile/page; POST /public/influencer-profile/page/generate, /submit, /page/publish и /page/unpublish; GET/POST /public/influencer-channels; GET/PUT /public/influencer-channels/{id}/pricing; POST /public/influencer-channels/{id}/ownership-challenge, /ownership-uploads, /ownership-uploads/{uploadId}/complete, /ownership-evidence и /submit. Профиль, страницы, каналы, ownership и pricing имеют JWT twins под /api/v1 без /public. GET/PUT /public/influencer-accounts/{accountId}/pricing — совместимый alias для собственного активного и верифицированного соцаккаунта; цены канала настраиваются через channel pricing. Совместимое поле publishAfterApproval принимает boolean: true публикует текущую версию сразу без предварительной модерации, false только создаёт private preview. Ручной канал создаётся через {kind:"MANUAL", platform, canonicalUrl}; безопасная публичная HTTPS-ссылка подходит для любой разрешённой платформы, а прежний запрос только с handle сохранён для Twitch/Kick. Проверка владения необязательна и не блокирует публикацию или покупку. Нативный аккаунт должен оставаться активным, верифицированным, принадлежать креатору и не быть заблокированным, приостановленным, проданным или удалённым. Отдельный JWT-only маршрут POST /api/v1/creator/social-accounts/{id}/avatar/refresh обновляет аватар своего аккаунта без нового OAuth; URL в body передавать нельзя. В owner DTO поля socialAccountId и avatarUrl необязательны. MCP-инструмент для обновления аватара не добавляется.
- Рекламодатель: POST /public/placement-orders создаёт черновик; PATCH /public/placement-orders/{id} меняет его; POST /public/placement-orders/{id}/quote рассчитывает цену; POST /public/placement-orders/{id}/checkout подтверждает резерв. Для договорной цены доступны POST /public/placement-offers/quote и POST /public/placement-offers. Заказы и аналитика читаются через GET /public/placement-orders, GET /public/placement-orders/{id}, GET /public/analytics/placements и GET /public/placement-orders/{id}/analytics.
- После funding стороны заказа используют GET /public/placement-assignments, GET /public/placement-assignments/{id}, /events и /deliverables; доступны accept, decline, submit, approve, request-changes, cancel, issues и change-proposals (предложить/принять срок). Deliverable меняется через PUT /public/placement-assignments/{id}/deliverables/{deliverableId}; private uploads имеют create/complete и attached-result download. JWT twins работают под /api/v1 без /public. Staff использует отдельные JWT-only review routes.
Если публикация временно отключена, явный запрос сохраняет publish intent и отвечает 503 WRITE_NOT_AVAILABLE_FOR_FEATURE; после разрешённого включения повторите тот же запрос с тем же UUID Idempotency-Key. Это не создаёт staff review; уже опубликованные страницы остаются доступны, unpublish работает.
Пример создания заказа
curl -X POST 'https://api.vibevo.io/api/v1/public/placement-orders' \
-H "Authorization: Bearer $VIBEVO_API_KEY" \
-H 'Content-Type: application/json' \
-H 'Idempotency-Key: 7ddc2979-9a7f-4d4f-8f89-38ea3353e444' \
-d '{"items":[{"serviceListingId":7,"quantity":1,"discountBps":0,"dueAt":"2026-10-20T18:00:00.000Z","brief":"Mention the product during the broadcast.","results":[{"expectedAt":"2026-10-20T17:00:00.000Z"}],"rights":{}}]}'В results должно быть ровно столько обязательств, сколько выбрано размещений (1, 5 или 10); expectedAt — дата каждого выхода, dueAt — общий крайний срок. rights содержит согласованные условия использования.
Quote и подтверждение
POST /api/v1/public/placement-orders/{id}/quote
Idempotency-Key: <stable UUID>
{ "expectedVersion": 1 }
# Advertiser-safe quote projection
{
"data": {
"quoteId": "9e955328-7a2b-42a4-9963-330fcc83ad92",
"quoteVersion": 1, "orderId": 14,
"expiresAt": "2026-10-08T12:10:00.000Z",
"payloadHash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"currency": "USDT",
"items": [{"serviceListingId":7,"base":{"raw":"100000000","currency":"USDT","decimals":6},"brandFee":{"raw":"5000000","currency":"USDT","decimals":6},"total":{"raw":"105000000","currency":"USDT","decimals":6}}],
"totals": {"base":{"raw":"100000000","currency":"USDT","decimals":6},"brandFee":{"raw":"5000000","currency":"USDT","decimals":6},"total":{"raw":"105000000","currency":"USDT","decimals":6}}
}
}
POST /api/v1/public/placement-orders/{id}/checkout
Idempotency-Key: <new stable UUID>
{ "quoteId": "9e955328-7a2b-42a4-9963-330fcc83ad92", "quoteVersion": 1, "payloadHash": "<copy the quote hash>", "confirm": true }Quote возвращает рекламодателю базовую сумму, его комиссию и общий резерв. Клиент показывает эти суммы и явно подтверждает checkout с quoteId, quoteVersion, payloadHash и confirm:true. Комиссия и чистый доход креатора не входят в ответ рекламодателю. В собственном creator pricing креатор видит свою базовую сумму, комиссию и чистый доход; комиссия бренда туда не входит.
Пример приватного UGC-предложения
POST /api/v1/public/placement-offers/quote
Idempotency-Key: <stable UUID>
{
"origin": "CUSTOM",
"creatorPublicId": "d8e805e4-1ec5-4ab6-a734-4ea389cecc6c",
"serviceType": "UGC",
"proofModes": ["PRIVATE_FILE"],
"priceCents": "12000",
"expectedEndAt": "2026-10-20T18:00:00.000Z",
"quantity": 1,
"discountBps": 0,
"brief": "Create and deliver a short private product video.",
"results": [{"expectedAt":"2026-10-20T17:00:00.000Z","description":"Deliver the private video"}],
"rights": {"usage":"As agreed in the brief"}
}
# Quote response: { data: { quoteId, quoteVersion, payloadHash, items: [{ serviceListingId: null, base, brandFee, total }], totals, ... } }
POST /api/v1/public/placement-offers
Idempotency-Key: <new stable UUID>
{ "quoteId": "<quote ID>", "quoteVersion": 1, "payloadHash": "<quote hash>", "confirm": true }
# Without serviceListingId, only UGC + PRIVATE_FILE is accepted; do not send accountId or channelRef.При отсутствии serviceListingId допустимы только serviceType "UGC" и proofModes ["PRIVATE_FILE"]. Не отправляйте accountId или channelRef. Quote показывает рекламодателю базовую сумму, его комиссию и общий резерв; serviceListingId будет null. У FILE result channelRef и publishedRevision равны null; url/contentId также null, metrics пустой. Файл не получает публичный URL или social metrics.
Повторы и ошибки
UUID Idempotency-Key обязателен для profile PATCH, page/generate, channel create и pricing PUT, а также для order, assignment и ownership mutations, где это указано в контракте. При неизвестном результате повторяйте тот же метод, путь, UUID и body; тот же ключ с другим body/action/target даёт IDEMPOTENCY_CONFLICT. Операции проверяют свежую роль и ownership до replay. Profile PATCH возвращает сохранённый DTO, page/generate заново строит preview. Pricing PUT возвращает сохранённый operation/version и свежий current projection; replay не повторяет денежную операцию или изменение цены.
Структурные ошибки
Ответ ошибки содержит стабильное поле code и безопасное сообщение. Возможные коды: API_KEY_INVALID (401), API_KEY_MISSING_SCOPE / ROLE_NOT_ALLOWED / ACCOUNT_ACCESS_DENIED (403), RESOURCE_NOT_FOUND (404), INVALID_MONEY_PRECISION / INVALID_PROOF (400), VERSION_CONFLICT / QUOTE_EXPIRED / PRICE_CHANGED / IDEMPOTENCY_CONFLICT / INSUFFICIENT_FUNDS (409), RATE_LIMITED (429), SERVICE_UNAVAILABLE / PRIVATE_UPLOAD_SERVICE_UNAVAILABLE (503). Чужой или недоступный объект выглядит как not found.
Пример безопасного тела ошибки:
{"code":"IDEMPOTENCY_CONFLICT","message":"The idempotency key was used with a different payload."}Идентификация ключа
GET /me— данные текущего ключа (кто владелец, скоупы). Достаточно любого валидного ключа.
Кампании (для рекламодателя)
GET /campaigns— список ваших кампаний (бюджет, потрачено, статус). Скоупread. Курсорная пагинация.GET /campaigns/{id}— одна кампания. Скоупread.GET /campaigns/{id}/posts— посты кампании. Скоупread. Курсор + необязательный фильтр по статусу.GET /campaigns/{id}/creators— креаторы, агрегированные по аккаунту и отсортированные по просмотрам. Скоупread.GET /campaigns/{id}/tracking-links— трекинг-ссылки сuniqueClicks. Скоупread.GET /campaigns/{id}/posts/{postId}/proofs— скриншоты просмотров поста Instagram, новые сверху:id,takenAt,views(что прочитал тот же скан;null, если Instagram скрыл просмотры). Скоупread.GET /campaigns/{id}/posts/{postId}/proofs/{proofId}/image— один скриншот (JPEG): плитка рилса в профиле, как её показал Instagram, — превью, просмотры, ник и время UTC. Других роликов, постов и кампаний на нём нет. Скоупread.GET /campaigns/{id}/proofs/zip— ZIP с последним скриншотом каждого поста Instagram кампании и таблицейindex.csv(пост, ссылка, аккаунт, рилс, время, просмотры). Скоупread.
ER и сохранения
ER = 100 × (likes + comments) / views, с округлением до двух знаков. Он считается по последним полным наблюдениям просмотров, лайков и комментариев. Итог использует суммы этих счётчиков, а не среднее процентов постов. При нулевых просмотрах или отсутствии полного наблюдения ER равен null. Сохранения и репосты в формулу не входят.
Список и карточка кампании, её аналитика, посты и креаторы возвращают engagement со scope: accepted_video. В расчёт входят только принятые видеопосты; в строке поста — только этот пост, в строке креатора — его аккаунт. Для знаменателя используйте engagement.views: прежний totalViews может включать другие статусы или отражать оплаченные просмотры.
В фабриках канонический ER находится в metrics.er (в сводке — totals.er), сохранения — в metrics.saves. Те же поля доступны в точках истории и snapshotBaseline. Прежнее верхнеуровневое er сохраняет старую семантику; новые клиенты используют вложенное поле. Отсутствие новых полей в старом ответе не подтверждает измерение.
saves — отдельный последний известный счётчик. Автоматические источники: TikTok collectCount и X bookmarkCount, только когда поставщик вернул корректное значение. На остальных платформах он недоступен без фактического измерения. 0 означает измеренный ноль, null — отсутствие данных. Не подменяйте null нулём. Старая история кампаний не доказывает исходное число просмотров: новый ER появится после обычного скана, без массового платного перескана.
erCoverage и savesCoverage содержат measuredPosts / totalPosts для всей выбранной выборки до пагинации. Частичное покрытие означает частичный итог. updatedAt и savesUpdatedAt — самое раннее время включённого измерения; null означает неизвестную свежесть. Перенос старого счётчика в новый снимок не обновляет его время. ER и сохранения на графиках — абсолютные снимки, без режима прироста.
В hiddenFields отчёта можно передать saves: сервер уберёт число, покрытие и время измерения. Скрытие views, likes, comments или er также убирает зависимый ER; скрытие posts — покрытие, lastScanned — время измерения. Эти правила действуют для сводок, строк, истории и baseline.
{
"engagement": {
"scope": "accepted_video",
"views": 100,
"likes": 0,
"comments": 0,
"er": 0,
"saves": null,
"erCoverage": { "measuredPosts": 1, "totalPosts": 2 },
"savesCoverage": { "measuredPosts": 0, "totalPosts": 2 },
"updatedAt": "2026-10-09T08:00:00.000Z",
"savesUpdatedAt": null
}
}Офферы (для креатора)
GET /offers— лента доступных офферов (RUNNING-кампаний, которые креатор может взять), с полями оффера: ставка/CPM, требования,takenAt. Без бюджета/потраченного рекламодателя. Скоупread. Курсорная пагинация.GET /posts— ваши поданные посты по всем кампаниям: статус, просмотры, заработок, кампания, аккаунт, дата подачи; плюсsummary(всего постов, на модерации, заработано всего). Скоупread. Курсор + необязательные фильтрыstatus,platform.GET /posts/{id}/proofsиGET /posts/{id}/proofs/{proofId}/image— скриншоты просмотров вашего поста Instagram: список и сам JPEG. Скоупread.
Соцаккаунты (для креатора)
GET /social-accounts— ваши соцаккаунты: платформа, ник, статус,isVerified,verifiedVia(PLATFORM_API/BIO_CODE/MANUAL),statsAvailabilityи подключениеsocialConnection, если оно есть. Скоупread.GET /social-accounts/{id}/verification— активный код для bio-верификации и инструкция, что с ним делать. Скоупread.GET /social-accounts/{id}/stats— статистика аккаунта: текущая сессия записи экрана, снапшот аудитории и история. Скоупread.
Фабрики контента
GET /factories— список фабрик с агрегатами по аккаунтам, постам и просмотрам.GET /factories/{id}/summary— сводка: публикации, просмотры, реакции, средние и медианные просмотры.GET /factories/{id}/accountsиGET /factories/{id}/accounts/{accountId}— креаторы и детальная аналитика одного аккаунта.GET /factories/{id}/posts— посты с обложкой, длительностью, хэштегами, метриками и мини-графиками.
Для сводки, креаторов и постов доступны фильтры from, to, platform, search, tag и factoryAccountId, а также сортировки accountSort и postSort. Списки используют курсорную пагинацию.
Теги, мониторинг и отчёты
Управляйте аккаунтами, тегами, мониторингом и публичными отчётами фабрики через API.
GET /factories/tags—readGET /factories/{id}/tag-groups—readGET /factories/credits—readGET /factories/{id}/credits—readGET /factories/{id}/credit-usage—readGET /factories/{id}/credit-history—readGET /factories/{id}/share-links—read
Интервалы: 24, 12, 10, 8, 6, 4 часа от последнего скана; срок 1–365 дней. В REST: scansPerPostPerDay = 24 / intervalHours. История содержит только начисления и списания, расходы — за всё время, 30 дней и сегодня UTC.
Если id не указан, инструменты расходов и истории используют /factories/credits/usage и /factories/credits/history для общего кошелька, включая покупки.
hiddenFields скрывает поля на сервере, включая производные значения и ссылки. По умолчанию видны все поля. Доступ к чужим фабрикам и админским отчётам не открывается. Скопируйте sharePath при создании — секрет повторно не выдаётся.
Аналитика
GET /analytics/campaigns/{id}— аналитика кампании. Скоупread.
Кошелёк
GET /wallet— текущий баланс. Скоупread.GET /wallet/transactions— история биллинга. Скоупread. Курсорная пагинация.
Курсорная пагинация
Списочные эндпоинты используют курсорную пагинацию. Передайте limit (от 1 до 100) и cursor (идентификатор последнего элемента предыдущей страницы):
GET /api/v1/public/campaigns?limit=50&cursor=1234Ответ содержит массив данных и курсор следующей страницы:
{
"data": [ /* ... */ ],
"nextCursor": "5678"
}Когда nextCursor равен null, страниц больше нет.
Формат денег
Денежные значения возвращаются структурой:
{
"raw": "1500",
"currency": "USD",
"decimals": 2
}raw — целое число в минимальных единицах, переданное строкой; реальное значение = raw / 10^decimals. Обратите внимание на разные масштабы:
- Бюджеты кампаний и заработок по постам — центы:
decimals: 2, валютаUSD(например,raw: "1500"= 15.00 USD). - Баланс кошелька и транзакции биллинга — минимальные единицы USDT:
decimals: 6.
Формат ошибок
Ошибки возвращаются единым конвертом:
{
"statusCode": 403,
"code": "insufficient_scope",
"message": "Missing required scope: read",
"timestamp": "2026-07-11T12:00:00.000Z",
"path": "/api/v1/public/campaigns"
}Ориентируйтесь на строковое поле code для программной обработки — оно стабильнее, чем человекочитаемый message.
Примеры curl
Список кампаний (заголовок Bearer):
curl https://api.vibevo.io/api/v1/public/campaigns?limit=20 \
-H "Authorization: Bearer vibevo_live_ab12cd.xxxxxxxxxxxxxxxx"Баланс кошелька (заголовок X-API-Key):
curl https://api.vibevo.io/api/v1/public/wallet \
-H "X-API-Key: vibevo_live_ab12cd.xxxxxxxxxxxxxxxx"Была ли эта статья полезна?
Обновлено: 9 октября 2026