TEXTAGRAM.ru API

Документация API для генерации описания товара по фотографии

Вы можете интегрировать функциональность TEXTAGRAM в свои системы и приложения с помощью нашего API. Для этого нужно зарегистрироваться в TEXTAGRAM.ru и получить API KEY в профиле.

Для всех запросов необходимо передавать API KEY в HTTP-заголовке Authorization:

Authorization: Bearer <API_KEY>

Запрос: генерация текстов по фото

POST /api/text/product

Вызов генерирует карточку товара и возвращает сгенерированные тексты (описание, заголовки и др.).

Параметры запроса (JSON)

Поле Тип Обяз. Описание
image_url string | array Да Изображение товара: ссылка на изображение ИЛИ строка data:image/...;base64,... ИЛИ «чистая» base64-строка. Можно передать несколько фото одного товара массивом строк — тогда все они учитываются в одной генерации. Максимальное число фото зависит от тарифа; за превышение возвращается ошибка. Генерация в любом случае списывает 1 кредит независимо от числа фото.
short_description string (max: 500) Да Краткое описание товара.
product_facts object Нет Известные характеристики товара. Допустимые поля: brand, model, material, composition, dimensions, weight, color, size, quantity, country, certificates, compatibility, package_contents. Значения — строки до 250 символов; числа передавайте вместе с единицами как строку. Вложенные объекты, массивы и неизвестные поля не принимаются. Доступно на всех тарифах.
style string Да Стиль оформления описания (допустимые значения: 'standard','playful','marketing','friendly','storytelling').
length integer Нет Желаемая длина описания: от 200 до меньшего из 3000 и лимита вашего тарифа. По умолчанию — 300, с ограничением по тарифу.
headers boolean | string | nullable Нет Если передано true (для совместимости также "headers") — дополнительно генерируются заголовки (поле headers в ответе).
slogans boolean | string | nullable Нет Если передано true (для совместимости также "slogans") — дополнительно генерируются рекламные слоганы (поле slogans в ответе).
creativity string | nullable Нет Уровень креативности текста: low, middle, high. balanced поддерживается как синоним middle. Опция должна быть доступна на тарифе.

Дополнительно можно передать keywords (до 500 символов, 20 фраз через запятую, до 100 символов на фразу) при доступности опции на тарифе. Флаги features и audience включают или выключают соответствующие блоки; по умолчанию они включены, если доступны на тарифе. headers и slogans по умолчанию выключены. Для всех флагов используйте JSON true / false; массивы и произвольные строки не принимаются.

Пример характеристик: {"product_facts":{"brand":"Samsung","model":"Galaxy S24","material":"пластик","dimensions":"10 × 15 см"}}. Это сведения, подтверждённые пользователем; сервис не проверяет их независимо. При расхождении с коротким описанием они имеют приоритет. Если явно видимая деталь фотографии противоречит текстовым сведениям, спорное свойство опускается. Ключевые слова не подтверждают свойства товара. Названия брендов и моделей могут оставаться в оригинальном написании.

Для повтора после потери ответа передайте заголовок Idempotency-Key (1–100 латинских букв, цифр или символов ._:-) либо поле request_id. Сохраняйте ключ и исходные поля запроса: успешный повтор возвращает прежний результат без новой генерации и списания. Новая попытка после ошибки генерации требует нового ключа; кредит освобождается.

Ответ (200 OK)

{
  "success": true,
  "error": null,
  "data": {
    "uid": "01JABCDEFGH...",
    "created_at": "2025-08-23T12:34:56.000000Z",
    "style": "standard",
    "style_name": "Стандартный",
    "description": "...сгенерированный текст...",
    "description_length": 234,
    "features": ["..."],
    "audience": "...описание целевой аудитории...",
    "headers": ["..."],
    "slogans": ["..."],
    "images": ["products/xxxx/yyyy.jpg"]
  }
}

Поля features (характеристики) и audience (целевая аудитория) возвращаются, если соответствующие опции доступны на вашем тарифе; headers и slogans — если они были запрошены (см. параметры выше) и доступны на тарифе. Иначе приходят пустыми ([] или null).

Ошибка содержит success: false, стабильный code, русское message и совместимое поле error. Неверные параметры или фото — HTTP 422 (invalid_parameters, image_invalid); отсутствующий тариф, API-доступ, недоступная опция или недостаточный баланс — HTTP 403 (plan_required, api_unavailable, tariff_option_unavailable, insufficient_credits). Повтор работающей операции — 409 (generation_in_progress), изменённые поля с прежним ключом — 409 (idempotency_conflict), удалённый результат — 410 (result_deleted). Ошибки генерации — 502: сбой провайдера (generation_failed), отказ модели (generation_refused), незавершённый ответ (generation_incomplete), пустой ответ (generation_empty), нарушение схемы или длины (generation_invalid_response), фото временно недоступно — 502 (image_unavailable), внутренняя недоступность — 500/503 (generation_unavailable). Ограничители частоты и размера могут вернуть 429/413.

Описание проверяется по фактической длине: от 80% до 115% запрошенного объёма, с пробелами, без маркеров **. Запрошенные списки содержат ровно предусмотренное тарифом число непустых строк; аудитория — непустую строку. Лишние или отсутствующие блоки отклоняются. Карточка создаётся только после успешной проверки; при ошибке AI кредит освобождается.

Примеры вызова

PHP (Guzzle)

<?php
require __DIR__ . '/vendor/autoload.php';

use GuzzleHttp\Client;

$baseUrl = 'http://textagram.loc';
$token   = '1|YOUR_TOKEN_HERE';

// Варианты image_url: обычный URL, data:image/...;base64,... или «чистая» base64-строка
$imageUrl = 'https://via.placeholder.com/300';

$client = new Client(['base_uri' => $baseUrl, 'timeout' => 30, 'http_errors' => false]);

$payload = [
    'image_url' => $imageUrl,
    'short_description' => 'Краткое описание товара',
    'style' => 'standard',
    // 'creativity' => 'balanced',
    // 'length' => 200,
];

$response = $client->post('/api/text/product', [
    'headers' => [
        'Authorization' => 'Bearer ' . $token,
        'Accept'        => 'application/json',
        'Content-Type'  => 'application/json',
    ],
    'json' => $payload,
]);

echo $response->getStatusCode() . "\n";
echo (string) $response->getBody() . "\n";

Python (requests)

import requests

base_url = 'http://textagram.loc'
token    = '1|YOUR_TOKEN_HERE'

headers = {
    'Authorization': f'Bearer {token}',
    'Accept': 'application/json',
    'Content-Type': 'application/json',
}

payload = {
    'image_url': 'https://via.placeholder.com/300',
    'short_description': 'Краткое описание товара',
    'style': 'standard',
    # 'creativity': 'balanced',
    # 'length': 200,
}

r = requests.post(base_url + '/api/text/product', json=payload, headers=headers, timeout=30)
print(r.status_code)
print(r.text)

Node.js (axios)

import axios from 'axios';

const baseUrl = 'http://textagram.loc';
const token   = '1|YOUR_TOKEN_HERE';

const payload = {
  image_url: 'https://via.placeholder.com/300',
  short_description: 'Краткое описание товара',
  style: 'standard',
  // creativity: 'balanced',
  // length: 200,
};

axios.post(baseUrl + '/api/text/product', payload, {
  headers: {
    Authorization: `Bearer ${token}`,
    Accept: 'application/json',
    'Content-Type': 'application/json',
  },
  timeout: 30000,
}).then(res => {
  console.log(res.status);
  console.log(res.data);
}).catch(err => {
  if (err.response) {
    console.error(err.response.status, err.response.data);
  } else {
    console.error(err.message);
  }
});