AACFlow

Внешний API

AACFlow предоставляет комплексный внешний API для запросов логов выполнения рабочих процессов и настройки вебхуков для получения уведомлений в реальном времени при завершении рабочих процессов.

Аутентификация

Все запросы к API требуют ключ API, передаваемый в заголовке x-api-key:

curl -H "x-api-key: YOUR_API_KEY" \
  https://aacflow.io/api/v1/logs?workspaceId=YOUR_WORKSPACE_ID

Вы можете сгенерировать ключи API на платформе AACFlow, перейдя в Настройки, затем в Ключи AACFlow и нажав Создать.

API логов

Все ответы API включают информацию о ваших лимитах выполнения рабочих процессов и использовании:

"limits": {
  "workflowExecutionRateLimit": {
    "sync": {
      "requestsPerMinute": 150,  // Устойчивый лимит запросов в минуту
      "maxBurst": 300,           // Максимальная емкость для всплесков
      "remaining": 298,          // Текущие доступные токены (до maxBurst)
      "resetAt": "..."           // Когда токены пополнятся в следующий раз
    },
    "async": {
      "requestsPerMinute": 1000, // Устойчивый лимит запросов в минуту
      "maxBurst": 2000,          // Максимальная емкость для всплесков
      "remaining": 1998,         // Текущие доступные токены
      "resetAt": "..."           // Когда токены пополнятся в следующий раз
    }
  },
  "usage": {
    "currentPeriodCost": 1.234,  // Использование в текущем биллинговом периоде в USD
    "limit": 10,                  // Лимит использования в USD
    "plan": "pro",                // Текущий тарифный план
    "isExceeded": false           // Превышен ли лимит
  }
}

Примечание: Лимиты скорости используют алгоритм токен-бакета. remaining может превышать requestsPerMinute до maxBurst, когда вы не использовали полный лимит недавно, что позволяет обрабатывать всплески трафика. Лимиты скорости в теле ответа относятся к выполнению рабочих процессов. Лимиты скорости для вызова этого конечного API находятся в заголовках ответа (X-RateLimit-*).

Запрос логов

Запрашивайте логи выполнения рабочих процессов с расширенными опциями фильтрации.

GET /api/v1/logs

Обязательные параметры:

  • workspaceId - ID вашего рабочего пространства

Опциональные фильтры:

  • workflowIds - ID рабочих процессов через запятую
  • folderIds - ID папок через запятую
  • triggers - Типы триггеров через запятую: api, webhook, schedule, manual, chat
  • level - Фильтр по уровню: info, error
  • startDate - Временная метка ISO для начала диапазона дат
  • endDate - Временная метка ISO для конца диапазона дат
  • executionId - Точное совпадение ID выполнения
  • minDurationMs - Минимальная длительность выполнения в миллисекундах
  • maxDurationMs - Максимальная длительность выполнения в миллисекундах
  • minCost - Минимальная стоимость выполнения
  • maxCost - Максимальная стоимость выполнения
  • model - Фильтр по используемой AI-модели

Пагинация:

  • limit - Результатов на страницу (по умолчанию: 100)
  • cursor - Курсор для следующей страницы
  • order - Порядок сортировки: desc, asc (по умолчанию: desc)

Уровень детализации:

  • details - Уровень детализации ответа: basic, full (по умолчанию: basic)
  • includeTraceSpans - Включать трассировочные спаны (по умолчанию: false)
  • includeFinalOutput - Включать финальный вывод (по умолчанию: false)
{
  "data": [
    {
      "id": "log_abc123",
      "workflowId": "wf_xyz789",
      "executionId": "exec_def456",
      "level": "info",
      "trigger": "api",
      "startedAt": "2025-01-01T12:34:56.789Z",
      "endedAt": "2025-01-01T12:34:57.123Z",
      "totalDurationMs": 334,
      "cost": {
        "total": 0.00234
      },
      "files": null
    }
  ],
  "nextCursor": "eyJzIjoiMjAyNS0wMS0wMVQxMjozNDo1Ni43ODlaIiwiaWQiOiJsb2dfYWJjMTIzIn0",
"limits": {
      "workflowExecutionRateLimit": {
        "sync": {
          "requestsPerMinute": 150,
          "maxBurst": 300,
          "remaining": 298,
          "resetAt": "2025-01-01T12:35:56.789Z"
        },
        "async": {
          "requestsPerMinute": 1000,
          "maxBurst": 2000,
          "remaining": 1998,
          "resetAt": "2025-01-01T12:35:56.789Z"
        }
      },
      "usage": {
        "currentPeriodCost": 1.234,
        "limit": 10,
        "plan": "pro",
        "isExceeded": false
      }
    }
}

Получение деталей лога

Получите подробную информацию о конкретной записи лога.

GET /api/v1/logs/{id}
{
  "data": {
    "id": "log_abc123",
    "workflowId": "wf_xyz789",
    "executionId": "exec_def456",
    "level": "info",
    "trigger": "api",
    "startedAt": "2025-01-01T12:34:56.789Z",
    "endedAt": "2025-01-01T12:34:57.123Z",
    "totalDurationMs": 334,
    "workflow": {
      "id": "wf_xyz789",
      "name": "Мой рабочий процесс",
      "description": "Обработка данных клиентов"
    },
    "executionData": {
      "traceSpans": [...],
      "finalOutput": {...}
    },
    "cost": {
      "total": 0.00234,
      "tokens": {
        "prompt": 123,
        "completion": 456,
        "total": 579
      },
      "models": {
        "gpt-4o": {
          "input": 0.001,
          "output": 0.00134,
          "total": 0.00234,
          "tokens": {
            "prompt": 123,
            "completion": 456,
            "total": 579
          }
        }
      }
    },
    "limits": {
      "workflowExecutionRateLimit": {
        "sync": {
          "requestsPerMinute": 150,
          "maxBurst": 300,
          "remaining": 298,
          "resetAt": "2025-01-01T12:35:56.789Z"
        },
        "async": {
          "requestsPerMinute": 1000,
          "maxBurst": 2000,
          "remaining": 1998,
          "resetAt": "2025-01-01T12:35:56.789Z"
        }
      },
      "usage": {
        "currentPeriodCost": 1.234,
        "limit": 10,
        "plan": "pro",
        "isExceeded": false
      }
    }
  }
}

Получение деталей выполнения

Получите детали выполнения, включая снимок состояния рабочего процесса.

GET /api/v1/logs/executions/{executionId}
{
  "executionId": "exec_def456",
  "workflowId": "wf_xyz789",
  "workflowState": {
    "blocks": {...},
    "edges": [...],
    "loops": {...},
    "parallels": {...}
  },
  "executionMetadata": {
    "trigger": "api",
    "startedAt": "2025-01-01T12:34:56.789Z",
    "endedAt": "2025-01-01T12:34:57.123Z",
    "totalDurationMs": 334,
    "cost": {...}
  }
}

Уведомления

Получайте уведомления в реальном времени при завершении выполнения рабочих процессов через вебхук, email или Slack. Уведомления настраиваются на уровне рабочего пространства на странице Логов.

Конфигурация

Настройте уведомления на странице Логов, нажав кнопку меню и выбрав "Настроить уведомления".

Каналы уведомлений:

  • Вебхук: Отправка HTTP POST запросов на ваш конечный URL
  • Email: Получение email-уведомлений с деталями выполнения
  • Slack: Отправка сообщений в канал Slack

Выбор рабочих процессов:

  • Выберите конкретные рабочие процессы для мониторинга
  • Или выберите "Все рабочие процессы" для включения текущих и будущих рабочих процессов

Опции фильтрации:

  • levelFilter: Уровни логов для получения (info, error)
  • triggerFilter: Типы триггеров для получения (api, webhook, schedule, manual, chat)

Опциональные данные:

  • includeFinalOutput: Включать финальный вывод рабочего процесса
  • includeTraceSpans: Включать детальные трассировочные спаны выполнения
  • includeRateLimits: Включать информацию о лимитах скорости (синхронные/асинхронные лимиты и оставшиеся)
  • includeUsageData: Включать данные об использовании и лимитах биллингового периода

Правила оповещений

Вместо получения уведомлений о каждом выполнении настройте правила оповещений, чтобы получать уведомления только при обнаружении проблем:

Последовательные сбои

  • Оповещение после X последовательных неудачных выполнений (например, 3 сбоя подряд)
  • Сбрасывается при успешном выполнении

Процент сбоев

  • Оповещение, когда процент сбоев превышает X% за последние Y часов
  • Требуется минимум 5 выполнений в окне
  • Срабатывает только после полного истечения временного окна

Порог задержки

  • Оповещение, когда любое выполнение занимает больше X секунд
  • Полезно для обнаружения медленных или зависших рабочих процессов

Скачок задержки

  • Оповещение, когда выполнение на X% медленнее среднего
  • Сравнивается со средней длительностью за настроенное временное окно
  • Требуется минимум 5 выполнений для установления базовой линии

Порог стоимости

  • Оповещение, когда одно выполнение стоит больше $X
  • Полезно для обнаружения дорогих вызовов LLM

Отсутствие активности

  • Оповещение, когда не происходит выполнений в течение X часов
  • Полезно для мониторинга запланированных рабочих процессов, которые должны выполняться регулярно

Количество ошибок

  • Оповещение, когда количество ошибок превышает X в пределах временного окна
  • Отслеживает общее количество ошибок, не последовательных

Все типы оповещений включают 1-часовой период охлаждения для предотвращения спама уведомлениями.

Конфигурация вебхука

Для вебхуков доступны дополнительные опции:

  • url: URL вашего конечного вебхука
  • secret: Опциональный секрет для проверки подписи HMAC

Структура полезной нагрузки

Когда выполнение рабочего процесса завершается, AACFlow отправляет следующую полезную нагрузку (через POST вебхука, email или Slack):

{
  "id": "evt_123",
  "type": "workflow.execution.completed",
  "timestamp": 1735925767890,
  "data": {
    "workflowId": "wf_xyz789",
    "executionId": "exec_def456",
    "status": "success",
    "level": "info",
    "trigger": "api",
    "startedAt": "2025-01-01T12:34:56.789Z",
    "endedAt": "2025-01-01T12:34:57.123Z",
    "totalDurationMs": 334,
    "cost": {
      "total": 0.00234,
      "tokens": {
        "prompt": 123,
        "completion": 456,
        "total": 579
      },
      "models": {
        "gpt-4o": {
          "input": 0.001,
          "output": 0.00134,
          "total": 0.00234,
          "tokens": {
            "prompt": 123,
            "completion": 456,
            "total": 579
          }
        }
      }
    },
    "files": null,
    "finalOutput": {...},  // Только если includeFinalOutput=true
    "traceSpans": [...],   // Только если includeTraceSpans=true
    "rateLimits": {...},   // Только если includeRateLimits=true
    "usage": {...}         // Только если includeUsageData=true
  },
  "links": {
    "log": "/v1/logs/log_abc123",
    "execution": "/v1/logs/executions/exec_def456"
  }
}

Заголовки вебхука

Каждый запрос вебхука включает эти заголовки (только для канала вебхука):

  • aacflow-event: Тип события (всегда workflow.execution.completed)
  • aacflow-timestamp: Временная метка Unix в миллисекундах
  • aacflow-delivery-id: Уникальный ID доставки для идемпотентности
  • aacflow-signature: Подпись HMAC-SHA256 для проверки (если настроен секрет)
  • Idempotency-Key: То же, что и ID доставки для обнаружения дубликатов

Проверка подписи

Если вы настроили секрет вебхука, проверьте подпись, чтобы убедиться, что вебхук от AACFlow:

import crypto from 'crypto';

function verifyWebhookSignature(body, signature, secret) {
  const [timestampPart, signaturePart] = signature.split(',');
  const timestamp = timestampPart.replace('t=', '');
  const expectedSignature = signaturePart.replace('v1=', '');
  
  const signatureBase = `${timestamp}.${body}`;
  const hmac = crypto.createHmac('sha256', secret);
  hmac.update(signatureBase);
  const computedSignature = hmac.digest('hex');
  
  return computedSignature === expectedSignature;
}

// В вашем обработчике вебхука
app.post('/webhook', (req, res) => {
  const signature = req.headers['aacflow-signature'];
  const body = JSON.stringify(req.body);
  
  if (!verifyWebhookSignature(body, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Обработать вебхук...
});
import hmac
import hashlib
import json

def verify_webhook_signature(body: str, signature: str, secret: str) -> bool:
    timestamp_part, signature_part = signature.split(',')
    timestamp = timestamp_part.replace('t=', '')
    expected_signature = signature_part.replace('v1=', '')
    
    signature_base = f"{timestamp}.{body}"
    computed_signature = hmac.new(
        secret.encode(),
        signature_base.encode(),
        hashlib.sha256
    ).hexdigest()
    
    return hmac.compare_digest(computed_signature, expected_signature)

# В вашем обработчике вебхука
@app.route('/webhook', methods=['POST'])
def webhook():
    signature = request.headers.get('aacflow-signature')
    body = json.dumps(request.json)
    
    if not verify_webhook_signature(body, signature, os.environ['WEBHOOK_SECRET']):
        return 'Invalid signature', 401
    
    # Обработать вебхук...

Политика повторных попыток

Неудачные доставки вебхуков повторяются с экспоненциальной задержкой и джиттером:

  • Максимальное количество попыток: 5
  • Задержки повторных попыток: 5 секунд, 15 секунд, 1 минута, 3 минуты, 10 минут
  • Джиттер: До 10% дополнительной задержки для предотвращения "стадного эффекта"
  • Только HTTP ответы 5xx и 429 запускают повторные попытки
  • Доставки таймаутят через 30 секунд

Доставки вебхуков обрабатываются асинхронно и не влияют на производительность выполнения рабочих процессов.

Лучшие практики

  1. Стратегия опроса: При опросе логов используйте пагинацию на основе курсора с order=asc и startDate для эффективного получения новых логов.

  2. Безопасность вебхуков: Всегда настраивайте секрет вебхука и проверяйте подписи, чтобы убедиться, что запросы от AACFlow.

  3. Идемпотентность: Используйте заголовок Idempotency-Key для обнаружения и обработки дублирующихся доставок вебхуков.

  4. Конфиденциальность: По умолчанию finalOutput и traceSpans исключены из ответов. Включайте их только если вам нужны эти данные и вы понимаете последствия для конфиденциальности.

  5. Лимитирование скорости: Реализуйте экспоненциальную задержку при получении ответов 429. Проверяйте заголовок Retry-After для рекомендуемого времени ожидания.

Лимитирование скорости

API использует алгоритм токен-бакета для лимитирования скорости, обеспечивая справедливое использование при разрешении всплесков трафика:

ТарифЗапросов/МинутуЕмкость для всплесков
Бесплатный3060
Pro100200
Team200400
Enterprise5001000

Как это работает:

  • Токены пополняются со скоростью requestsPerMinute
  • Вы можете накапливать до maxBurst токенов при простое
  • Каждый запрос потребляет 1 токен
  • Емкость для всплесков позволяет обрабатывать пики трафика

Информация о лимитах скорости включена в заголовки ответа:

  • X-RateLimit-Limit: Запросов в минуту (скорость пополнения)
  • X-RateLimit-Remaining: Текущие доступные токены
  • X-RateLimit-Reset: Временная метка ISO, когда токены пополнятся в следующий раз

Пример: Опрос новых логов

let cursor = null;
const workspaceId = 'YOUR_WORKSPACE_ID';
const startDate = new Date().toISOString();

async function pollLogs() {
  const params = new URLSearchParams({
    workspaceId,
    startDate,
    order: 'asc',
    limit: '100'
  });
  
  if (cursor) {
    params.append('cursor', cursor);
  }
  
  const response = await fetch(
    `https://aacflow.io/api/v1/logs?${params}`,
    {
      headers: {
        'x-api-key': 'YOUR_API_KEY'
      }
    }
  );
  
  if (response.ok) {
    const data = await response.json();
    
    // Обработать новые логи
    for (const log of data.data) {
      console.log(`Новое выполнение: ${log.executionId}`);
    }
    
    // Обновить курсор для следующего опроса
    if (data.nextCursor) {
      cursor = data.nextCursor;
    }
  }
}

// Опрашивать каждые 30 секунд
setInterval(pollLogs, 30000);

Пример: Обработка вебхуков

import express from 'express';
import crypto from 'crypto';

const app = express();
app.use(express.json());

app.post('/aacflow-webhook', (req, res) => {
  // Проверить подпись
  const signature = req.headers['aacflow-signature'];
  const body = JSON.stringify(req.body);
  
  if (!verifyWebhookSignature(body, signature, process.env.WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Проверить временную метку для предотвращения атак повторного воспроизведения
  const timestamp = parseInt(req.headers['aacflow-timestamp']);
  const fiveMinutesAgo = Date.now() - (5 * 60 * 1000);
  
  if (timestamp < fiveMinutesAgo) {
    return res.status(401).send('Timestamp too old');
  }
  
  // Обработать вебхук
  const event = req.body;
  
  switch (event.type) {
    case 'workflow.execution.completed':
      const { workflowId, executionId, status, cost } = event.data;
      
      if (status === 'error') {
        console.error(`Рабочий процесс ${workflowId} завершился с ошибкой: ${executionId}`);
        // Обработать ошибку...
      } else {
        console.log(`Рабочий процесс ${workflowId} завершен: ${executionId}`);
        console.log(`Стоимость: $${cost.total}`);
        // Обработать успешное выполнение...
      }
      break;
  }
  
  // Вернуть 200 для подтверждения получения
  res.status(200).send('OK');
});

app.listen(3000, () => {
  console.log('Вебхук-сервер слушает на порту 3000');
});

Common Questions

On this page

Начните создавать сегодня
Нам доверяют более 100 000 разработчиков.
SaaS-платформа для создания AI-агентов и управления агентным workforce.
Начать