Публичный API + n8n

Для авторов и администраторов клубов, которые ведут контент через автоматизации: отправляйте посты в Amator из n8n, скрипта или любого инструмента, который умеет делать HTTP-запросы.

Что это даёт

Один эндпоинт публикует текстовый пост от вашего имени — в одно из двух мест:

  • В вашу личную ленту — просто не передавайте club_id.
  • В клуб, которым вы управляете, — передайте его club_id. Вы должны быть владельцем или администратором клуба — то же правило, что и для публикаций от имени клуба в приложении.

Как получить API-ключ

  1. Откройте приложение Amator и перейдите в Настройки › API-ключи.
  2. Нажмите Создать и назовите ключ так, чтобы потом его узнать, например «n8n».
  3. Сразу скопируйте ключ — он показывается только один раз. Если потеряете, отзовите его и создайте новый.

Храните ключ как пароль: любой, у кого он есть, может публиковать от вашего имени. Любой ключ можно отозвать в любой момент на том же экране — после этого запросы с ним отклоняются.

Эндпоинт

POST https://api.amator.app/api/v1/public/posts

Отправьте тело запроса в JSON, а ключ передайте в заголовке X-API-KEY (не Authorization: Bearer).

  • content string — текст поста, от 1 до 2000 символов. Обязательное поле.
  • club_id uuid | null — клуб, от имени которого публикуете. Необязательное — без него пост появится в вашей ленте.

Пост в вашу ленту

curl -X POST https://api.amator.app/api/v1/public/posts \
  -H "X-API-KEY: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{"content":"Training moved to 19:00 tonight"}'

Пост от имени клуба

curl -X POST https://api.amator.app/api/v1/public/posts \
  -H "X-API-KEY: YOUR_API_KEY_HERE" \
  -H "Content-Type: application/json" \
  -d '{"content":"Match day! Kick-off at 18:00","club_id":"00000000-0000-0000-0000-000000000000"}'

Успешная публикация возвращает 201 и ссылку на пост:

HTTP/1.1 201 Created

{
  "success": true,
  "data": {
    "id": "…",
    "destination": "club",
    "club_id": "00000000-0000-0000-0000-000000000000",
    "created_at": "2026-10-05T18:00:00.000Z",
    "url": "https://web.amator.app/posts/…"
  },
  "requestId": "…"
}

Один пост в час — отдельно для каждого места

У каждого места публикации свой почасовой лимит: ваш профиль — одно место, каждый клуб — ещё одно. Лимиты никогда не объединяются: пост в одном месте не расходует лимит другого, а свободное место где-то ещё не поможет там, где лимит уже исчерпан.

  • OK Ваш профиль и клуб A в течение одного часа
  • OK Клубы A, B и C в течение одного часа
  • 429 Второй пост в клуб A в течение часа — 429, даже если профиль и другие клубы свободны

Когда лимит исчерпан, приходит 429 с заголовком Retry-After (в секундах) и подробностями в теле ответа:

HTTP/1.1 429 Too Many Requests
Retry-After: 2400

{
  "success": false,
  "error": {
    "code": "PUBLIC_API_RATE_LIMITED",
    "message": "This club already had its post this hour",
    "details": {
      "destination": "club",
      "club_id": "00000000-0000-0000-0000-000000000000",
      "retry_after_seconds": 2400,
      "next_allowed_at": "2026-10-05T19:00:00.000Z"
    }
  },
  "requestId": "…"
}

Прежде чем снова публиковать в это место, подождите не меньше Retry-After секунд или до next_allowed_at. Не повторяйте запросы в цикле.

Другие ответы

  • 400 FEED_POST_EMPTY
    Текст поста пустой или слишком длинный.
  • 401 PUBLIC_API_KEY_INVALID
    Ключа нет, он неизвестен или отозван.
  • 403 FEED_NOT_A_CAPTAIN
    Вы не владелец и не администратор этого клуба.
  • 404 FEED_TEAM_NOT_FOUND
    Клуба с таким club_id не существует.
  • 429 PUBLIC_API_RATE_LIMITED
    В это место уже публиковали в этот час.
  • 429 FEED_DAILY_LIMIT_REACHED
    Исчерпан дневной лимит ленты — 40 постов в день.

Готовый workflow для n8n

Пять узлов: ручной старт, узел Edit Fields с полями content и club_id, узел If, который проверяет, пусто ли club_id, и два узла HTTP Request — один публикует в ваш профиль, другой в клуб.

Workflow начинается с ручного триггера, чтобы его можно было проверить сразу после импорта. Когда всё заработает, замените Start на то, что действительно должно его запускать, — Schedule, RSS, форму — и передайте его данные в эти два поля.

Скачать .json
{
  "name": "Amator — publish a post",
  "nodes": [
    {
      "id": "7b0f3a52-1c6e-4d1b-9a43-5e2f8c1d0a01",
      "name": "Start",
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        0,
        0
      ],
      "parameters": {}
    },
    {
      "id": "7b0f3a52-1c6e-4d1b-9a43-5e2f8c1d0a02",
      "name": "Post content",
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        220,
        0
      ],
      "parameters": {
        "mode": "manual",
        "assignments": {
          "assignments": [
            {
              "id": "7b0f3a52-1c6e-4d1b-9a43-5e2f8c1d0b01",
              "name": "content",
              "value": "Hello from n8n! Training moved to 19:00 tonight.",
              "type": "string"
            },
            {
              "id": "7b0f3a52-1c6e-4d1b-9a43-5e2f8c1d0b02",
              "name": "club_id",
              "value": "",
              "type": "string"
            }
          ]
        },
        "options": {}
      }
    },
    {
      "id": "7b0f3a52-1c6e-4d1b-9a43-5e2f8c1d0a03",
      "name": "Club ID empty?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        440,
        0
      ],
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "loose",
            "version": 2
          },
          "conditions": [
            {
              "id": "7b0f3a52-1c6e-4d1b-9a43-5e2f8c1d0c01",
              "leftValue": "={{ $json.club_id }}",
              "rightValue": "",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "looseTypeValidation": true,
        "options": {}
      }
    },
    {
      "id": "7b0f3a52-1c6e-4d1b-9a43-5e2f8c1d0a04",
      "name": "Post to my profile",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        680,
        -120
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.amator.app/api/v1/public/posts",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-API-KEY",
              "value": "YOUR_API_KEY_HERE"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ content: $json.content }) }}",
        "options": {}
      }
    },
    {
      "id": "7b0f3a52-1c6e-4d1b-9a43-5e2f8c1d0a05",
      "name": "Post to club",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4.2,
      "position": [
        680,
        120
      ],
      "parameters": {
        "method": "POST",
        "url": "https://api.amator.app/api/v1/public/posts",
        "sendHeaders": true,
        "headerParameters": {
          "parameters": [
            {
              "name": "X-API-KEY",
              "value": "YOUR_API_KEY_HERE"
            }
          ]
        },
        "sendBody": true,
        "specifyBody": "json",
        "jsonBody": "={{ JSON.stringify({ content: $json.content, club_id: $json.club_id }) }}",
        "options": {}
      }
    }
  ],
  "connections": {
    "Start": {
      "main": [
        [
          {
            "node": "Post content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post content": {
      "main": [
        [
          {
            "node": "Club ID empty?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Club ID empty?": {
      "main": [
        [
          {
            "node": "Post to my profile",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Post to club",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {},
  "pinData": {}
}

Импорт в n8n

  1. Скопируйте JSON выше или скачайте файл.
  2. В n8n откройте Workflows, создайте новый workflow и вставьте скопированный JSON на пустой холст (Ctrl/Cmd+V). Файл можно импортировать через меню ⋯ › Import from File.
  3. В обоих узлах HTTP Request замените YOUR_API_KEY_HERE на свой ключ. А лучше сохраните его как учётные данные n8n (Header Auth, имя X-API-KEY).
  4. В узле Post content впишите текст в content. Оставьте club_id пустым, чтобы опубликовать в профиле, или вставьте ID клуба, чтобы опубликовать от его имени.
  5. Нажмите Execute workflow. Узел HTTP покажет ответ — при успехе 201 и url поста.