Перейти к содержимому

Проект, размещения и усиление через API

Один проект от черновика до отчёта и отдельной покупки усиления. На каждом шаге видно, какие данные взять из ответа для следующего запроса.

Подключитесь к API Zapost.im

Запросите у поддержки рабочий ключ zp_live_. Для полного цикла нужны read, projects:write и projects:pay. В черновике замените демонстрационный URL на страницу своего проекта. Запускайте команды по порядку в одном сеансе Bash с curl, jq и Node.js 24.

set -o pipefail
API_BASE='https://zapost.im/api/v2'
read -rsp 'API key: ' API_KEY
printf '\n'

api() {
  local path=$1
  shift
  curl --silent --show-error --fail-with-body \
    -H "Authorization: Bearer $API_KEY" "$@" "$API_BASE$path"
}

post() {
  api "$1" -H "Idempotency-Key: $2" \
    -H 'Content-Type: application/json' --data "$3"
}

new_key() { node -p 'crypto.randomUUID()'; }

api /packages | jq '.data[] | {code, name, price, placements, page_limit}'
api /balance | jq '.data | {available, currency}'

Выберите code из каталога. В примере используется пакет start. Все суммы в ответах указаны в целых копейках.

Создайте проект

Передайте пакет, целевую страницу, описание сайта и требования к сообщению. Сохраните id проекта и его revision из ответа. Усиление купим отдельно после получения размещений.

PACKAGE_CODE='start'
CREATE_KEY=$(new_key)
DRAFT=$(jq -cn --arg package "$PACKAGE_CODE" --arg ref "demo-$CREATE_KEY" '{
  package_code: $package, external_id: $ref,
  urls: ["https://example.test/catalog"],
  brief: "Online shop for camping equipment",
  notes: "Link to the catalog in a relevant discussion",
  amplification_level: null
}')
PROJECT=$(post /projects "$CREATE_KEY" "$DRAFT")
PROJECT_ID=$(jq -er '.data.id' <<< "$PROJECT")
REVISION=$(jq -er '.data.revision' <<< "$PROJECT")
jq '.data | {id, revision, status}' <<< "$PROJECT"

Для каждого нового действия создавайте отдельный Idempotency-Key. Если результат запроса неизвестен, повторите только строку с post с теми же ключом и телом. Сохраните эти значения, если повторять будете в другом сеансе.

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

Возьмите цену выбранного пакета из каталога и проверьте доступный баланс. Покажите цену человеку перед оплатой. В этом примере усиление покупается отдельно.

EXPECTED_AMOUNT=$(api /packages | jq -er --arg code "$PACKAGE_CODE" \
  '.data[] | select(.code == $code) | .price')
jq -n --argjson amount "$EXPECTED_AMOUNT" '{expected_amount: $amount}'
api /balance | jq '.data | {available, currency}'

Подтвердите оплату проекта

После подтверждения отправьте revision проекта и expected_amount в копейках. Этот запрос списывает средства с баланса аккаунта. Проверьте результат по payment_id.

PAY_KEY=$(new_key)
PAY_BODY=$(jq -cn --argjson revision "$REVISION" --argjson amount "$EXPECTED_AMOUNT" \
  '{revision: $revision, expected_amount: $amount}')
PAYMENT=$(post "/projects/$PROJECT_ID/payments" "$PAY_KEY" "$PAY_BODY")
PAYMENT_ID=$(jq -er '.data.id' <<< "$PAYMENT")
api "/projects/$PROJECT_ID/payments/$PAYMENT_ID" |
  jq '.data | {id, status, amount, currency}'

При 409 revision_conflict или amount_changed списания нет. Перечитайте проект и каталог и снова покажите сумму человеку. При нехватке средств пополните баланс вручную. После подтверждённого отказа используйте новый ключ для новой попытки оплаты.

Получите прогресс и размещения

После оплаты читайте статус и прогресс проекта. Отчёт может быть пустым сразу после покупки. Ссылка появляется в API, когда менеджер вносит её в отчёт. Менеджер завершает проект отдельно. Для примера используйте limit=1, чтобы увидеть переход на следующую страницу.

api "/projects/$PROJECT_ID" | jq '.data | {status, progress}'
PLACEMENTS="/projects/$PROJECT_ID/placements"
PAGE=$(api "$PLACEMENTS?limit=1")
jq '{data, progress, revision, pagination}' <<< "$PAGE"

NEXT=$(jq -r '.pagination.next_cursor // empty' <<< "$PAGE")
REPORT_REVISION=$(jq -er '.revision' <<< "$PAGE")
if [ -n "$NEXT" ]; then
  PAGE=$(api "$PLACEMENTS" --get --data-urlencode 'limit=1' \
    --data-urlencode "cursor=$NEXT" \
    --data-urlencode "revision=$REPORT_REVISION")
  jq '{data, progress, revision, pagination}' <<< "$PAGE"
fi
Фрагмент ответа
{
  "id": "10000000-0000-4000-8000-000000000001",
  "url": "https://forum.example.test/topic/1#message-7",
  "target_url": "https://example.test/catalog",
  "recorded_at": "2026-11-06T12:00:00Z",
  "verification_status": "unchecked"
}

Сохраняйте id каждого размещения. Если пара url и target_url меняется, размещение получает новый id. recorded_at показывает время внесения ссылки в отчёт. Для остальных страниц берите next_cursor из последнего ответа и сохраняйте revision и limit. При 409 placements_changed начните заново. Заменяйте локальный список только после успешного обхода до next_cursor=null.

Выберите уровень усиления

Используйте тот же PROJECT_ID. Проверьте amplification.can_purchase в свежей карточке проекта. Выберите доступный уровень из каталога усиления для купленного пакета. В примере это basic. Проверьте цену этого уровня перед оплатой.

PROJECT=$(api "/projects/$PROJECT_ID")
REVISION=$(jq -er '.data.revision' <<< "$PROJECT")
jq '.data.amplification | {can_purchase, unavailable_reason}' <<< "$PROJECT"
LEVEL='basic'
AMP_AMOUNT=$(api /amplification-packages | jq -er \
  --arg code "$PACKAGE_CODE" --arg level "$LEVEL" \
  '.data[] | select(.package_code == $code) | .levels[] | select(.level == $level) | .price')
jq -n --argjson amount "$AMP_AMOUNT" '{expected_amount: $amount}'

Оплатите усиление и проверьте его статус

После отдельного подтверждения передайте level, revision проекта и expected_amount за усиление в копейках. Платёж покрывает только усиление. Проверьте результат оплаты и прочитайте состояние усиления в карточке проекта.

AMP_PAY_KEY=$(new_key)
AMP_PAY_BODY=$(jq -cn --argjson revision "$REVISION" --arg level "$LEVEL" \
  --argjson amount "$AMP_AMOUNT" '{revision: $revision, level: $level, expected_amount: $amount}')
AMP_PATH="/projects/$PROJECT_ID/amplification"
AMP_PAYMENT=$(post "$AMP_PATH/payments" "$AMP_PAY_KEY" "$AMP_PAY_BODY")
AMP_PAYMENT_ID=$(jq -er '.data.id' <<< "$AMP_PAYMENT")
api "/projects/$PROJECT_ID/payments/$AMP_PAYMENT_ID" |
  jq '.data | {id, purpose, status, amount, currency}'
api "/projects/$PROJECT_ID" |
  jq '.data.amplification | {purchase, current}'

В результате оплаты purpose=amplification. Успешная оплата подтверждает покупку. Ожидание публикаций и фактический запуск отслеживайте по current.status и current.started_at.