Publicaciones
Publicar una publicación
Las apps live publican al instante, programan o guardan un borrador; las de prueba solo simulan. Con ?dry_run=true se comprueba todo y no se escribe nada.
Una publicación pertenece a un establecimiento y sale hacia una o varias redes, sus destinos. Cada destino tiene su propio texto, sus archivos, su formato y su estado.
Tipo de publicación: ahora, programada o borrador
Dos campos del cuerpo deciden cuándo, y si, sale la publicación:
| Caso | Cuerpo | Comportamiento |
|---|---|---|
| Ahora | sin scheduledAt | La publicación sale enseguida. |
| Programada | scheduledAt: una fecha-hora ISO 8601 futura | Saldrá en scheduledAt. |
| Borrador | "status": "draft", sin scheduledAt | Se guarda y no sale. |
El cuerpo de una publicación
| Campo | Significado |
|---|---|
establishmentId | El establecimiento que publica (GET /v1/establishments) |
targets[] | Una entrada por red: platform, text y, opcionalmente, media, format y accountId |
targets[].media[] | Un archivo de la biblioteca multimedia por su id, o una url https pública con su type (image o video) |
targets[].accountId | La cuenta que se usará cuando el establecimiento tiene varias en esa red |
scheduledAt | Una fecha-hora ISO 8601 futura; si no aparece, la publicación sale enseguida |
status | draft para guardar un borrador que no sale (entonces sin scheduledAt) |
Archivos de un destino
Cada entrada de targets[].media designa un archivo de la biblioteca multimedia por su id, o una url https pública con su type (image o video). Instagram y TikTok exigen una foto o un vídeo. Para añadir un archivo a la biblioteca multimedia, consulta Importar un archivo.
Duplicar una publicación
No existe un endpoint específico para duplicar una publicación: léela con `GET /v1/posts/{id}` y vuelve a enviar su contenido en una nueva solicitud POST /v1/posts.
Antes de reenviarla, quita los campos que rellena Sofia por sí misma. Como mínimo:
idycreatedAtde la publicación;statusde la publicación leída (resume el estado de envío): fija el que quieras, u omítelo;- en cada destino:
state,publishedAt,permalinkyerror.
Conserva establishmentId y, para cada destino, platform y accountId. La lectura no devuelve el texto de los destinos ni sus archivos: facilítalos de nuevo. Por último, fija un nuevo scheduledAt (u omítelo para publicar enseguida, o envía "status": "draft").
Tu primera publicación
1. Comprobar las redes conectadas
Una publicación sale por las cuentas conectadas al establecimiento. Lístalas; si falta alguna, crea un enlace de conexión. Consulta Cuentas conectadas.
2. Añadir un archivo
Instagram y TikTok exigen una foto o un vídeo. Importa uno desde una URL https pública; Sofia lo descarga en la biblioteca multimedia y devuelve su id. Consulta Importar un archivo.
3. Comprobar con una simulación
Añade ?dry_run=true: Sofia juzga cada red según sus reglas reales y la cuenta conectada, y no escribe nada.
curl -X POST 'https://api.sofia-post.com/api/v1/posts?dry_run=true' \
-H "Authorization: Bearer $SOFIA_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"establishmentId": "'$ESTABLISHMENT_ID'",
"targets": [
{ "platform": "instagram", "text": "Tarte tatin du jour", "media": [{ "id": "'$MEDIA_ID'" }] },
{ "platform": "facebook", "text": "Tarte tatin du jour", "media": [{ "id": "'$MEDIA_ID'" }] }
]
}'{
"status": "ready",
"dryRun": true,
"targets": [
{ "platform": "instagram", "accountId": "fecd0904-…", "handle": "sof_ia_officiel", "state": "ready" },
{ "platform": "facebook", "accountId": "a423b3a4-…", "handle": "Sofia post", "state": "ready" }
]
}4. Publicar
Envía el mismo cuerpo sin dry_run, con una Idempotency-Key para que un nuevo intento nunca publique dos veces. Sin scheduledAt, la publicación sale enseguida; con un scheduledAt futuro, queda programada.
curl -X POST https://api.sofia-post.com/api/v1/posts \
-H "Authorization: Bearer $SOFIA_API_KEY" \
-H 'Content-Type: application/json' \
-H "Idempotency-Key: $(uuidgen)" \
-d @post.json5. Seguirla
La publicación responde publishing, y luego cada red pasa a published con su enlace permanente, o a failed con su motivo. Léela con `GET /v1/posts/{id}`, o registra un webhook para recibir un aviso.
Simulación (dry run)
POST /v1/posts?dry_run=true ejecuta las comprobaciones de una publicación real: las reglas de cada red, la cuenta conectada, los archivos, la fecha y tu plan. No guarda nada y no envía nada.
Lista
Cuando cada red aceptaría la publicación, la respuesta es 200 con status: "ready" y, para cada destino, la cuenta que publicaría.
Rechazada
Si no, la respuesta es 422 post_refused, con un detalle por motivo. Cada detalle nombra su red, su code, y dice qué corregir.
{
"error": {
"code": "post_refused",
"message": "The post would not be published: x: the text is too long (300 characters, at most 280)",
"details": [
{
"platform": "x",
"code": "caption_too_long",
"max": 280,
"actual": 300,
"message": "x: the text is too long (300 characters, at most 280)"
}
],
"docUrl": "https://www.sofia-post.com/developers/errors#post_refused"
}
}Cada motivo está listado en los errores.
Para el modo de prueba de las aplicaciones, consulta Modo de prueba y simulación. Una Idempotency-Key también protege POST /v1/posts: consulta Idempotencia.
Autorizaciones
AuthorizationstringheaderobligatorioTu clave personal o token de acceso OAuth, enviado como
Bearer <token>.
Parámetros de consulta
dry_runstringtrue: ejecuta todas las comprobaciones del envío (reglas de las redes, cuentas, medios, creación, suscripción live) y no escribe nada. Devuelve 200readyo 422post_refused.Valores permitidos:
truefalse
Cabeceras
Idempotency-KeystringRepetida con el mismo cuerpo, la petición devuelve la misma respuesta sin crear una segunda publicación. Una simulación no consume la clave.
Cuerpo
establishmentIdstringobligatorioEstablecimiento, en el Workspace de la autorización del token (
GET /v1/establishments)targetsobject[]obligatorioUna red por destino
Mostrar atributos hijos
platformstringobligatorioRed de destino
Valores permitidos:
instagramfacebookxlinkedintiktoktextstringobligatorioPie publicado en esta red
mediaobject[]Medios adjuntos
Mostrar atributos hijos
idstringIdentificador de un medio de la biblioteca del establecimiento (si no,
urlytype)urlstringDirección pública del medio (https en live); sin identificador
typestringTipo del medio dado por dirección
Valores permitidos:
imagevideo
formatstringFormato (
post,reel,story,carousel...); por defecto, el que serviría la redaccountIdstringLive: la cuenta conectada que publica, cuando el establecimiento tiene varias en esta red (
GET /v1/establishments/:id/accounts)
scheduledAtstring<date-time>Fecha de programación (ISO 8601), en el futuro; ausente: publicar de inmediato. No permitida con
statusdraftstatusstringdraft: un borrador (solo live), creado sin fecha, no se envía nada;PATCH /v1/posts/:idlo programaValores permitidos:
draft
Respuesta
Simulación: todas las comprobaciones han pasado.
statusstringobligatorioSiempre
readyValores permitidos:
readydryRunbooleanobligatorioSiempre
trueValores permitidos:
truetargetsobject[]obligatorioLos destinos comprobados
Mostrar atributos hijos
platformstringobligatorioRed del destino
statestringobligatorioSiempre
readyValores permitidos:
readyaccountIdstringLive: la cuenta que publicaría
handlestringLive: su identificador visible