ContentFlow AI โ API REST
Automatiza la generacion y publicacion de contenido de marketing a escala.
Servidores environments
https://api.contentflow.ai/v1
Production
https://staging-api.contentflow.ai/v1
Staging
http://localhost:3000/v1
Local Dev
Campanas campaigns
GET
/v1/campaigns
Listar campanas paginadas
Devuelve una lista cursor-based de campanas del workspace. Soporta filtrado por estado, marca y fechas. Requiere autenticacion Bearer.
| Parametro | Tipo | Ubicacion | Descripcion |
|---|---|---|---|
| cursor | string | query | Cursor de paginacion (opaco) |
| limit | integer | query | Items por pagina [1-50], default 20 |
| status | CampaignStatus | query | draft | active | completed | archived |
| brand_id | uuid | query | Filtrar por brand kit |
Respuestas
200
Lista paginada de campanas
CampaignListResponse
401
Token invalido o expirado
Error
429
Rate limit excedido
Error
POST
/v1/campaigns
Crear nueva campana
Crea una nueva campana de contenido asociada a un brand kit. Devuelve la campana creada con su ID.
Request Body required
// application/json
{
"name": "Campana Verano 2026 โ NutriPaw",
"brand_id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
"channels": ["instagram", "tiktok", "email"],
"objective": "awareness",
"start_date": "2026-07-01",
"end_date": "2026-07-31",
"tone": "friendly",
"keywords": ["verano", "bienestar", "mascotas"],
"content_count": 12
}
Respuestas
201
Campana creada correctamente
Campaign
400
Validacion fallida (campos requeridos)
Error
404
Brand kit no encontrado
Error
POST
/v1/campaigns/{campaignId}/publish
Lanzar campana
Publica todos los contenidos aprobados en los canales configurados. Operacion asincrona: devuelve job_id para seguimiento.
202Publicacion encoladaPublishJob
409Campana sin contenidos aprobadosError
Generacion de Contenidos contents
POST
/v1/campaigns/{campaignId}/contents/generate
Disparar generacion IA
Lanza el pipeline de generacion IA para la campana. Utiliza el brand kit asociado como contexto. Operacion asincrona.
// Request body opcional
{
"model": "claude-3-7-sonnet-20250219",
"override_tone": "playful",
"regenerate_ids": ["uuid-1", "uuid-2"]
}
202Generacion en progresoGenerationJob
422Campana en estado invalidoError
POST
/v1/contents/{contentId}/approve
Aprobar pieza de contenido
Marca un contenido como aprobado para publicacion. Solo usuarios con rol editor o superior pueden aprobar.
200Contenido aprobadoContent
403Sin permisos de aprobacionError
409Ya aprobado previamenteError
POST
/v1/contents/{contentId}/reject
Rechazar con feedback
{
"reason": "tone_mismatch",
"feedback": "El tono es demasiado formal. Necesitamos algo mas cercano y desenfadado para el publico joven.",
"regenerate": true
}
200Contenido rechazado (+ job generacion si regenerate=true)Content
Schemas components/schemas
Campaign
object
id req
string (uuid)
Identificador unico de la campana
name req
string
Nombre legible, min 1 / max 200 chars
status req
CampaignStatus
draft | active | completed | archived
brand_id req
string (uuid)
Brand kit asociado
channels req
string[]
instagram | tiktok | linkedin | twitter | email | blog
content_count
integer
Numero de piezas a generar [1-100]
keywords
string[]
Palabras clave para la generacion
created_at req
string (date-time)
Timestamp de creacion (readOnly)
Content
object
id req
string (uuid)
ID unico de la pieza
campaign_id req
string (uuid)
Campana propietaria
channel req
string
Canal destino de la pieza
copy
string
Texto generado / editado
image_url
string (uri) | null
URL de imagen generada
approval_status req
ApprovalStatus
pending | approved | rejected | published
rejection_reason
string | null
Motivo del rechazo si aplica
Error
object
code req
string
VALIDATION_ERROR | NOT_FOUND | UNAUTHORIZED | RATE_LIMITED | CONFLICT
message req
string
Mensaje legible por humano
details
object[]
Array de {field, message} para errores de validacion
request_id req
string
ID unico de la peticion (para soporte)
Autenticacion securitySchemes
bearerAuth (JWT)
Token JWT obtenido en
/auth/login. Incluir en header Authorization.
Authorization: Bearer <token>
apiKey
API Key para integraciones service-to-service. Generada desde el dashboard.
X-API-Key: cf_live_xxxxxxxxxxxx
Rate Limits por tier de workspace
500
requests / minuto
Plan Standard
5.000
requests / minuto
Plan Enterprise
# Headers de rate limit en cada respuesta
X-RateLimit-Limit: 500
X-RateLimit-Remaining: 487
X-RateLimit-Reset: 1750100460
Retry-After: 13 # solo en 429
contentflow-api.openapi.yaml
OAS 3.1.0
openapi: 3.1.0
info:
title: ContentFlow AI API
description: |
API REST para la plataforma de generacion y publicacion de contenido IA.
## Autenticacion
La mayoria de endpoints requieren JWT Bearer. Las integraciones
service-to-service pueden usar API Key via header X-API-Key.
## Rate Limiting
- 500 req/min en plan Standard
- 5.000 req/min en plan Enterprise
version: 1.0.0
contact:
name: API Support โ ContentFlow
email: api@contentflow.ai
url: https://docs.contentflow.ai
license:
name: MIT
servers:
- url: https://api.contentflow.ai/v1
description: Production
- url: https://staging-api.contentflow.ai/v1
description: Staging
- url: http://localhost:3000/v1
description: Local development
tags:
- name: Auth
description: Autenticacion y gestion de sesion
- name: Campaigns
description: Gestion del ciclo de vida de campanas
- name: Contents
description: Piezas de contenido generadas por IA
- name: Brands
description: Brand kits del workspace
paths:
/auth/login:
post:
operationId: loginUser
summary: Autenticar usuario y obtener JWT
tags: [Auth]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/LoginRequest'
responses:
'200':
description: Autenticacion correcta
content:
application/json:
schema:
$ref: '#/components/schemas/AuthTokens'
'401':
$ref: '#/components/responses/Unauthorized'
/campaigns:
get:
operationId: listCampaigns
summary: Listar campanas del workspace
tags: [Campaigns]
parameters:
- $ref: '#/components/parameters/CursorParam'
- $ref: '#/components/parameters/LimitParam'
- name: status
in: query
schema:
$ref: '#/components/schemas/CampaignStatus'
- name: brand_id
in: query
schema:
type: string
format: uuid
responses:
'200':
description: Lista paginada de campanas
content:
application/json:
schema:
$ref: '#/components/schemas/CampaignListResponse'
examples:
default:
value:
data:
- id: "a1b2c3d4-..."
name: "Campana Verano 2026 NutriPaw"
status: "active"
cursor:
next: "eyJpZCI6..."
has_more: true
'401':
$ref: '#/components/responses/Unauthorized'
'429':
$ref: '#/components/responses/RateLimited'
security:
- bearerAuth: []
- apiKey: []
post:
operationId: createCampaign
summary: Crear nueva campana
tags: [Campaigns]
requestBody:
required: true
content:
application/json:
schema:
$ref: '#/components/schemas/CreateCampaignRequest'
responses:
'201':
description: Campana creada
content:
application/json:
schema:
$ref: '#/components/schemas/Campaign'
headers:
Location:
description: URL del recurso creado
schema:
type: string
format: uri
components:
schemas:
Campaign:
type: object
required: [id, name, status, brand_id, channels, created_at]
properties:
id:
type: string
format: uuid
readOnly: true
name:
type: string
minLength: 1
maxLength: 200
status:
$ref: '#/components/schemas/CampaignStatus'
brand_id:
type: string
format: uuid
channels:
type: array
items:
type: string
enum: [instagram, tiktok, linkedin, twitter, email, blog]
minItems: 1
content_count:
type: integer
minimum: 1
maximum: 100
created_at:
type: string
format: date-time
readOnly: true
CampaignStatus:
type: string
enum: [draft, active, completed, archived]
Error:
type: object
required: [code, message, request_id]
properties:
code: { type: string }
message: { type: string }
details:
type: array
items:
type: object
properties:
field: { type: string }
message: { type: string }
request_id: { type: string }
securitySchemes:
bearerAuth:
type: http
scheme: bearer
bearerFormat: JWT
apiKey:
type: apiKey
in: header
name: X-API-Key
security:
- bearerAuth: []