Pular para o conteúdo
Entrar Lista de espera

Criar post

POST /v1/posts escopo write

Cria um post com um item por rede (fila, horário fixo ou rascunho). Cada item pode levar channel (a conta daquela rede; sem ele, vale o canal padrão). Com kind: "image" é um post de foto única, só no Instagram (pelo Buffer ou direto pela Meta).

CabeçalhosAuthorization: Bearer praeko_… e X-Praeko-Contract: en. Sempre envie os dois.

Parâmetros

Nome Onde Descrição
Idempotency-Key cabeçalho Chave de idempotência (1 a 255 caracteres visíveis, por exemplo um UUID). Repetir o MESMO pedido com a mesma chave, em até 24 h, devolve a resposta guardada (com Idempotent-Replayed: true) sem executar de novo; outro pedido com a mesma chave dá 422 idempotency_key_reuse; um pedido ainda em andamento dá 409 idempotency_in_progress. Erros 5xx não são guardados. A chave vale por workspace e por rota. Veja Repetir uma requisição.

Corpo da requisição

JSON. Campos obrigatórios precisam ir; os outros podem ser omitidos. O servidor devolve 422 invalid_request com a lista completa dos problemas em details.errors. A mídia precisa estar ready (completa). Post de imagem (kind: image): foto única no Instagram, pelo Buffer ou direto pela Meta. A foto é uma mídia type: image (JPEG); o Instagram aceita JPEG de até 8 MB com proporção de 4:5 a 1,91:1 (use 1080x1350). O item pode voltar com warnings (code estável): alt_ignored (o Buffer não tem texto alternativo), image_small, image_will_be_resized, image_dimensions_unknown. O post volta com kind e media.images.

Campo Tipo Descrição
title (opcional) texto Título do post. Obrigatório, a não ser que texts.youtube.title exista. Até 200 caracteres.
baseText (opcional) texto Texto base, guardado junto ao post.
kind (opcional) texto video (padrão) ou image: foto única, só Instagram. YouTube e TikTok recusam image (422 kind_not_supported_by_network). Valores: video, image; padrão: video.
media obrigatório objeto Mídias do post (ids de POST /v1/media, já completadas).
media.video (opcional) texto Id da mídia de vídeo. Obrigatório quando kind é video.
media.cover (opcional) texto Id da mídia de capa (PNG ou JPEG). Só em post de vídeo.
media.images (opcional) objeto[] Só com kind: image: a foto do post, UMA por enquanto (várias seriam um carrossel, que chega numa fase futura: 422 carousel_not_supported). Até 1 itens.
media.images[].media obrigatório texto Id de uma mídia type: image já completada.
media.images[].alt (opcional) texto Texto alternativo (até 1000 caracteres). Vai para o Instagram quando o item publica pela Meta (via: meta); pelo Buffer é ignorado e o item volta com o aviso alt_ignored. Até 1000 caracteres.
texts obrigatório objeto Textos por rede. Cada rede de items precisa ter o seu text.
texts.youtube (opcional) objeto Textos do YouTube.
texts.youtube.title (opcional) texto Título do vídeo (até 100 caracteres; mais longo é cortado).
texts.youtube.text obrigatório texto Descrição.
texts.youtube.pinnedComment (opcional) texto Comentário fixo, publicado depois que o vídeo fica público.
texts.instagram (opcional) objeto Textos do Instagram.
texts.instagram.text obrigatório texto Legenda: até 2200 caracteres e 30 hashtags.
texts.instagram.pinnedComment (opcional) texto Comentário fixo.
texts.tiktok (opcional) objeto Textos do TikTok.
texts.tiktok.text obrigatório texto Legenda: até 2200 caracteres.
items obrigatório objeto[] Um item por rede (não pode repetir a rede).
items[].network obrigatório texto Rede do item. Valores: youtube, instagram, tiktok.
items[].channel (opcional) texto Id da conta daquela rede (de GET /v1/channels). Sem ele, o canal padrão.
items[].mode (opcional) texto Como publicar. YouTube: private, scheduled ou public. TikTok: draft ou direct. Instagram: now. Valores: private, scheduled, public, draft, direct, now; padrão: private no YouTube, draft no TikTok, now no Instagram.
items[].scheduledFor (opcional) texto Horário fixo da publicação. Data e hora ISO 8601 em UTC, por exemplo 2026-11-14T20:30:00Z. No mínimo 30 s à frente (Instagram: 5 min pelo Buffer, 25 min pela Meta; YouTube scheduled: 5 min).
items[].queue (opcional) verdadeiro/falso true usa o próximo horário livre do canal (veja PUT /v1/channels/:network/slots).
items[].via (opcional) texto Só Instagram: por onde publicar. Valores: meta, buffer.
items[].replaces (opcional) objeto Só Instagram com via: meta: apaga este post do Buffer ao publicar.
items[].replaces.provider obrigatório texto Sempre buffer. Valores: buffer.
items[].replaces.id obrigatório texto Id do post no Buffer.
items[].media (opcional) objeto Mídias só deste item (trocam as do post). Só video e cover: imagens por item chegam numa fase futura.
items[].media.video (opcional) texto Id da mídia de vídeo.
items[].media.cover (opcional) texto Id da mídia de capa.
queue (opcional) verdadeiro/falso Vale para todos os itens que não trouxerem queue nem scheduledFor.
draft (opcional) verdadeiro/falso true cria tudo como rascunho (sem horário obrigatório). Padrão: false.
options (opcional) objeto Opções por rede e gerais.
options.format (opcional) texto long marca o post como vídeo longo (sem ele, é um Short). Valores: long.
options.youtube (opcional) objeto Opções do YouTube.
options.youtube.mode (opcional) texto O mesmo de items[].mode. Valores: private, scheduled, public.
options.youtube.categoryId (opcional) texto Categoria do vídeo. Padrão: 28.
options.youtube.tags (opcional) string[] Etiquetas do vídeo.
options.youtube.notifySubscribers (opcional) verdadeiro/falso Avisar os inscritos.
options.youtube.comment (opcional) verdadeiro/falso false não publica o comentário fixo.
options.tiktok (opcional) objeto Opções do TikTok.
options.tiktok.mode (opcional) texto O mesmo de items[].mode. Valores: draft, direct.
options.tiktok.privacy (opcional) texto Quem vê. Valores: PUBLIC_TO_EVERYONE, MUTUAL_FOLLOW_FRIENDS, FOLLOWER_OF_CREATOR, SELF_ONLY; padrão: SELF_ONLY.
options.tiktok.coverFrameMs (opcional) inteiro Quadro do vídeo usado como capa, em milissegundos. Mínimo 0.
options.tiktok.disableComments (opcional) verdadeiro/falso Desligar comentários.
options.tiktok.disableDuet (opcional) verdadeiro/falso Desligar dueto.
options.tiktok.disableStitch (opcional) verdadeiro/falso Desligar stitch.
options.tiktok.commercialContent (opcional) verdadeiro/falso Conteúdo comercial (exige ownBrand e/ou thirdPartyBrand).
options.tiktok.ownBrand (opcional) verdadeiro/falso Divulga a própria marca.
options.tiktok.thirdPartyBrand (opcional) verdadeiro/falso Divulga marca de terceiros (não pode ser SELF_ONLY no modo direct).
options.instagram (opcional) objeto Opções do Instagram.
options.instagram.via (opcional) texto Por onde publicar. Valores: meta, buffer.
options.instagram.shareToFeed (opcional) verdadeiro/falso Mostrar também no feed. Padrão: true.
options.instagram.coverFrameMs (opcional) inteiro Quadro do vídeo usado como capa, em milissegundos. Mínimo 0.
tags (opcional) string[] Etiquetas do post (até 40 caracteres cada). Cada um com até 40 caracteres.
id (opcional) texto Id escolhido por você (3 a 64 caracteres entre letras, números, - e _). Sem ele, o servidor gera. Repetido dá 409 id_exists.
origin (opcional) texto Quem criou o post (texto livre; padrão api).
Exemplo de corpo
{
  "title": "O teste que só falhava na segunda",
  "media": {
    "video": "01KA3VQ7M2T9XE4HB8N5RZ6C0D"
  },
  "texts": {
    "youtube": {
      "title": "O teste que só falhava na segunda",
      "text": "Um teste que passava de terça a domingo. O que ele escondia.\n\n#programação #testes"
    }
  },
  "items": [
    {
      "network": "youtube",
      "mode": "scheduled",
      "scheduledFor": "2026-11-10T20:30:00.000Z"
    }
  ],
  "tags": [
    "bastidores"
  ]
}

Exemplo

curl -X POST "https://praeko.app/v1/posts" \
  -H "Authorization: Bearer $PRAEKO_KEY" \
  -H "X-Praeko-Contract: en" \
  -H "Content-Type: application/json" \
  -d '{
  "title": "O teste que só falhava na segunda",
  "media": {
    "video": "01KA3VQ7M2T9XE4HB8N5RZ6C0D"
  },
  "texts": {
    "youtube": {
      "title": "O teste que só falhava na segunda",
      "text": "Um teste que passava de terça a domingo. O que ele escondia.\n\n#programação #testes"
    }
  },
  "items": [
    {
      "network": "youtube",
      "mode": "scheduled",
      "scheduledFor": "2026-11-10T20:30:00.000Z"
    }
  ],
  "tags": [
    "bastidores"
  ]
}'

Resposta

Status de sucesso Quando
201 Sucesso.
Resposta 201
{
  "id": "01KA3W2Y6H1RC5ZQ8M0T4VXE7N",
  "items": [
    {
      "id": "01KA3W2Y6J9D3BNF7G2K5PQS8A",
      "network": "youtube",
      "channel": "01KA3V0R5D8M2WQ7X4HT9NZ1BF",
      "state": "scheduled",
      "scheduledFor": "2026-11-10T20:30:00.000Z",
      "custom": true,
      "mode": "scheduled",
      "runAt": "2026-11-10T19:30:00.000Z"
    }
  ]
}

Erros

Status code Quando
400 empty_body O corpo veio vazio.
400 invalid_json O corpo não é um objeto JSON.
413 body_too_large O corpo passa de 1 MB.
422 invalid_request Faltou algo; a lista completa vem em details.errors.
422 invalid_field Id, canal, modo ou etiqueta inválidos.
422 time_in_past O horário já passou ou está perto demais.
422 missing_schedule Faltou scheduledFor, queue ou draft.
409 channel_not_connected A rede não está conectada.
409 no_slots queue num canal sem horários.
409 id_exists Já existe um post com esse id.
409 media_not_ready A mídia ainda não foi concluída.
422 media_not_found A mídia não existe.
422 media_type_mismatch A mídia não é do tipo certo (kind: image pede type: image).
422 kind_not_supported_by_network kind: image num item de YouTube ou TikTok.
422 carousel_not_supported Mais de uma imagem em media.images (carrossel chega depois).
422 invalid_image A imagem não é JPEG (o Instagram só aceita JPEG).
422 image_too_large A imagem passa de 8 MB (limite do Instagram).
422 image_aspect_ratio A proporção da imagem fica fora de 4:5 a 1,91:1 (o Instagram recusaria; use 1080x1350).
422 idempotency_key_reuse A Idempotency-Key já foi usada com outro pedido (método, caminho, query ou corpo diferentes).
409 idempotency_in_progress Um pedido com a mesma Idempotency-Key ainda está em andamento (repita em instantes).
409 idempotency_response_too_large A resposta original passou de 256 KB e não foi guardada; consulte o recurso por GET.

Erros de qualquer rota

Status code Quando
401 unauthorized Faltou o cabeçalho Authorization: Bearer ….
401 invalid_api_key A chave não existe.
401 revoked_api_key A chave foi revogada.
401 expired_api_key A chave expirou.
403 forbidden O escopo da chave não basta para esta rota (veja o selo de escopo).
429 rate_limited Passou do limite de requisições por minuto.

O corpo de todo erro é { "error": { "code", "message", "details"? } }. Veja todos os códigos.

Testar

Testar

O teste ao vivo usa a sua chave e a sua conta. Para quem não entrou, fica desligado.

Entre para testar
Dúvida ou erro nesta página? contato@praeko.appVer .md

Digite para buscar páginas, rotas e códigos de erro.