TL;DR, Resposta Rápida
8 min de leituraO Mastodon documenta que o scheduled_at precisa estar pelo menos 5 minutos no futuro, e o código sustenta isso com MINIMUM_OFFSET = 5.minutes em ScheduledStatus. Qualquer coisa mais perto devolve HTTP 422 com um erro de validação. Um timestamp no passado se comporta de outro jeito: o PostStatusService descarta o valor e publica o status na hora. Outros dois limites, 300 status agendados no total e 25 por dia, aparecem só no código-fonte.
Qual é o offset mínimo de scheduled_at na API do Mastodon?
Todo valor de scheduled_at da API do Mastodon precisa cair mais de 5 minutos à frente do relógio do servidor, senão POST /api/v1/statuses rejeita a requisição com HTTP 422. A documentação de form-data desse endpoint diz isso em uma linha: "Datetime at which to schedule a status. Providing this parameter will cause ScheduledStatus to be returned instead of Status. Must be at least 5 minutes in the future."
O endpoint de atualização repete a regra com palavras um pouco diferentes. O PUT /api/v1/scheduled_statuses/:id documenta o próprio scheduled_at como "Datetime at which the status will be published. Must be at least 5 minutes into the future", então mover um post já agendado para menos de cinco minutos falha do mesmo jeito que criar um.
O número não é uma convenção de documentação. É uma constante no modelo, MINIMUM_OFFSET = 5.minutes.freeze em app/models/scheduled_status.rb, e a validação que a usa é esta:
def validate_future_date
errors.add(:scheduled_at, I18n.t('scheduled_statuses.too_soon')) if scheduled_at.present? && scheduled_at <= Time.now.utc + MINIMUM_OFFSET
endA comparação é <=, então um timestamp exatamente 5 minutos à frente falha. "At least 5 minutes" na documentação significa estritamente mais de 5 minutos no código.
O que a API devolve quando o horário está perto demais?
Um 422 com uma mensagem de validação no campo error. O tratamento de erros da API do Mastodon transforma a exceção do Rails direto em JSON:
rescue_from ActiveRecord::RecordInvalid, Mastodon::ValidationError do |e|
render json: { error: e.to_s }, status: 422
endEsse concern vive em app/controllers/concerns/api/error_handling.rb e é incluído pelo Api::BaseController, então o corpo é a string da própria exceção, e não um código legível por máquina. Não há código de erro, lista de campos nem dica de retry-after; interpretar isso significa casar com texto em inglês.
Por que a string de erro documentada difere da que os servidores enviam?
Porque a string de locale mudou e o exemplo da documentação não. A página scheduled_statuses mostra este corpo de 422 para o endpoint de atualização:
{
"error": "Validation failed: Scheduled at The scheduled date must be in the future"
}O config/locales/en.yml atual na branch main de mastodon/mastodon traz uma frase mais curta:
scheduled_statuses:
over_daily_limit: You have exceeded the limit of %{limit} scheduled posts for today
over_total_limit: You have exceeded the limit of %{limit} scheduled posts
too_soon: date must be in the futureO Rails prefixa o nome humanizado do atributo, então um servidor atual produz "Validation failed: Scheduled at date must be in the future". O exemplo documentado ainda carrega a redação antiga, "The scheduled date must be in the future".
| Fonte | String |
|---|---|
| docs.joinmastodon.org, exemplo de 422 em scheduled_statuses | "Validation failed: Scheduled at The scheduled date must be in the future" |
config/locales/en.yml, branch main | "Validation failed: Scheduled at date must be in the future" |
Qualquer cliente que compare exatamente com a frase documentada vai perder o erro em um servidor atual. Compare pelo status 422 e pela presença de scheduled_at na sua própria requisição, não pela frase.

O que acontece se o scheduled_at estiver no passado?
O post sai na hora, e nenhum erro é levantado. Esse é o comportamento que a documentação nunca menciona, e ele vive no PostStatusService:
@scheduled_at = @options[:scheduled_at]&.to_datetime
@scheduled_at = nil if scheduled_in_the_past?com
def scheduled_in_the_past?
@scheduled_at.present? && @scheduled_at <= Time.now.utc
endDefinir @scheduled_at como nil faz scheduled? ser falso, o que leva a requisição por process_status! em vez de schedule_status!. A resposta é uma entidade Status, não ScheduledStatus, então um cliente que presume que scheduled_at sempre devolve um ScheduledStatus vai ler um id ausente para um post que já está público.
Três resultados, um parâmetro:
AdaptlyPost
Comece seu teste grátis de 7 dias
Análises multiplataforma
Caixa Social
Assistente com IA
Valor de scheduled_at | Resultado | Resposta |
|---|---|---|
| No passado, ou exatamente agora | Publicado na hora | Status |
| Dentro de 5 minutos a partir de agora | Rejeitado | 422, erro de validação |
| Mais de 5 minutos à frente | Enfileirado | ScheduledStatus |
A faixa do meio é a armadilha. Um loop de retry que empurra um envio falho para "alguns minutos depois" cai direto no 422; um que recorre a publicar agora mandando um timestamp no passado ganha um post ao vivo em vez do erro que esperava.
- Cai dentro da faixa de 5 minutos
- O servidor responde com 422
- Envia um timestamp no passado
- PostStatusService descarta scheduled_at
- O status é publicado imediatamente
Quantos status agendados uma conta pode manter?
Mais dois limites ficam ao lado do offset no mesmo modelo, e nenhum dos dois aparece na documentação da API:
TOTAL_LIMIT = 300
DAILY_LIMIT = 25
MINIMUM_OFFSET = 5.minutes.freezeO TOTAL_LIMIT limita quantos status agendados uma conta pode ter na fila ao mesmo tempo, e a mensagem é "You have exceeded the limit of 300 scheduled posts". O DAILY_LIMIT limita quantos podem dividir a mesma data do calendário, validado com scheduled_at::date = ?::date contra o banco, e a mensagem é "You have exceeded the limit of 25 scheduled posts for today".
Os dois chegam no mesmo formato de 422, com a mensagem em base e não em scheduled_at. Uma fila que carrega um mês de posts de uma vez bate na parede dos 25 por dia muito antes dos 300 no total, e nada em docs.joinmastodon.org avisa sobre nenhum dos dois.
Que formato o scheduled_at aceita?
Um datetime RFC 3339, que o Mastodon documenta à parte como seu formato de data e hora: [YYYY]-[MM]-[DD]T[hh]:[mm]:[ss].[s][TZD], em que o designador de fuso é Z para UTC ou um offset como +02:00. A documentação é explícita ao dizer que o separador é um T maiúsculo e que o Z é sempre maiúsculo.
A validação compara contra Time.now.utc no servidor, não no cliente. O desvio do relógio do cliente come direto da margem de cinco minutos, o que é um bom motivo para agendar a seis ou sete minutos em vez de cinco minutos e um segundo. O mesmo modo de falha aparece sempre que uma fila confia no horário local, como acontece entre Mastodon e Bluesky e em qualquer outra API que valida contra o próprio relógio.

Como mudar ou cancelar um status agendado?
Três endpoints cuidam da fila depois da criação. O GET /api/v1/scheduled_statuses lista os agendamentos, com 20 resultados por padrão e máximo de 40. O PUT /api/v1/scheduled_statuses/:id recebe um novo scheduled_at, sujeito à mesma regra de 5 minutos. O DELETE /api/v1/scheduled_statuses/:id cancela um e devolve um objeto vazio.
Mudar o texto é outra operação. O Mastodon observa que PUT /api/v1/statuses/:id edita um status já publicado, e que "To edit the scheduled_at attribute of a ScheduledStatus to change the publication date, use the scheduled status endpoint." O conteúdo de um post na fila vive no objeto params da entidade ScheduledStatus e o endpoint de atualização aceita apenas a data, então mudar a redação significa apagar e recriar.
Um status na fila que não existe mais devolve 404 com {"error": "Record not found"}, que é também o que devolve um status agendado pertencente a outra conta.
O que o piso de 5 minutos significa para uma fila de publicação?
Ele define o menor intervalo útil entre decidir postar e postar. Qualquer coisa abaixo de cinco minutos precisa sair como status imediato e não como agendado, então um agendador precisa de um desvio, e não de um caminho único: abaixo do limite, descarte o scheduled_at e publique; acima dele, enfileire e guarde o id do ScheduledStatus devolvido.
Outros dois números pertencem à mesma rodada de planejamento. O tamanho padrão de post do Mastodon é de 500 caracteres, coberto em o limite de caracteres do Mastodon, e o rate limiting por servidor fica por cima de tudo isso, do mesmo jeito que o Bluesky publica os próprios rate limits de API separadamente das regras de post. Montar o calendário em torno do piso da plataforma, e não das preferências de uma ferramenta, é o hábito geral por trás de agendar posts em redes sociais com confiabilidade.
Uma ressalva cobre todos os números acima. As constantes vêm da branch main de mastodon/mastodon, e um servidor rodando um fork ou uma versão mais antiga pode ter valores diferentes, então leia o corpo do 422 em vez de presumir que 5, 25 e 300 valem em todo lugar.
Perguntas frequentes
O scheduled_at aceita um horário exatamente 5 minutos à frente?
Não. A validação compara com <=, então scheduled_at <= Time.now.utc + 5.minutes falha. A frase documentada "at least 5 minutes in the future" significa estritamente mais de cinco minutos quando você lê o código-fonte.
Que status HTTP o Mastodon devolve para um scheduled_at cedo demais?
- O Mastodon resgata
ActiveRecord::RecordInvalide renderiza{ error: e.to_s }com status 422, então o corpo é uma frase de validação em inglês simples em vez de um objeto de erro estruturado.
Qual versão do Mastodon adicionou o scheduled_at?
2.7.0. O histórico de versões na documentação de POST /api/v1/statuses lista "2.7.0 - scheduled_at added", e os três endpoints de scheduled_statuses entraram no mesmo release.
AdaptlyPost
Comece seu teste grátis de 7 dias
Análises multiplataforma
Caixa Social
Assistente com IA
Um post agendado devolve um Status ou um ScheduledStatus?
Um ScheduledStatus, sempre que o scheduled_at é aceito. O Mastodon afirma que o endpoint "Returns: Status. When scheduled_at is present, ScheduledStatus is returned instead." A exceção é um timestamp no passado, porque o servidor descarta o parâmetro e publica na hora, devolvendo um Status.
Dá para agendar mais de 25 posts do Mastodon para o mesmo dia?
Não em um servidor padrão. O DAILY_LIMIT = 25 em app/models/scheduled_status.rb conta os status agendados que já dividem a mesma data e rejeita o vigésimo sexto com "You have exceeded the limit of 25 scheduled posts for today". Um TOTAL_LIMIT = 300 separado limita a fila inteira. Nenhum dos dois números aparece na documentação da API.
Onde o mínimo de 5 minutos está documentado?
Na página de métodos de statuses em docs.joinmastodon.org/methods/statuses/, no parâmetro de form-data scheduled_at, e de novo em docs.joinmastodon.org/methods/scheduled_statuses/ para o endpoint de atualização. A constante por trás dele é MINIMUM_OFFSET = 5.minutes.freeze em app/models/scheduled_status.rb no repositório mastodon/mastodon.
Quantos resultados o GET /api/v1/scheduled_statuses devolve por padrão?
Vinte. O endpoint devolve 20 status agendados por página por padrão, com um máximo de 40, então uma conta perto do limite total de 300 precisa de várias requisições para percorrer toda a fila.
O que acontece se você consultar um status agendado que já foi cancelado?
O servidor responde com 404 e {"error": "Record not found"}. É a mesma resposta de um status agendado que pertence a outra conta, então um 404 aqui não diferencia entre "nunca existiu", "já foi cancelado" e "não é seu".
Dá para editar o texto de um status agendado no Mastodon?
Editar o texto significa apagar o status agendado e criar um novo, não modificá-lo no lugar. O endpoint de atualização só aceita um novo scheduled_at, e o conteúdo de um status na fila vive no objeto params da entidade ScheduledStatus.
Com quanto tempo de antecedência você deveria realmente agendar um post no Mastodon?
Mais de cinco minutos, e seis ou sete minutos são mais seguros do que cinco minutos e um segundo. A validação compara com o relógio do servidor, não com o do cliente, então qualquer atraso no horário local corrói exatamente essa margem.
Coloque isso em prática com o AdaptlyPost
Este artigo foi útil para você?
Conte-nos o que você achou!
Veja-nos mais no Google
Um clique marca a AdaptlyPost como fonte preferida e nossos artigos passam a aparecer mais acima nas suas Principais notícias, no modo IA e nas visões gerais com IA.
Antes de ir...
AdaptlyPost
Agende seu conteúdo em todas as plataformas
Gerencie todas as suas contas de redes sociais em um só lugar com o AdaptlyPost.
Análises multiplataforma
Caixa Social
Assistente com IA
Termos relacionados do glossário


O que o endpoint content_publishing_limit do Instagram devolve
O endpoint content_publishing_limit do Instagram devolve quota_usage mais um bloco config com quota_total 50 e quota_duration de 86400 segundos.


Como funciona o token de acesso de longa duração do Facebook e os 60 dias dele
Um token de acesso de longa duração do Facebook dura cerca de 60 dias, e o token de Página derivado dele não tem data de expiração. Veja a chamada de troca.


Como ler o status_code do contêiner do Instagram antes de publicar
Cada valor do status_code do contêiner do Instagram que a Meta documenta, a cadência de polling recomendada, a expiração em 24 horas e o que fazer no ERROR.
Artigos Relacionados


Por que um access token do LinkedIn expira depois de 60 dias
Todo access token do LinkedIn dura 60 dias e o expires_in devolve 5184000. Regras do refresh token, o que mata um token antes e os 60 dias da Meta.


Como funciona o limite de 250 posts por dia da API do Threads
A Meta conta o limite de 250 posts por dia da API do Threads em uma janela móvel. Carrosséis contam uma vez, e um endpoint diz quanto sobrou no perfil.


Como o chunk_size da API do TikTok e o total_chunk_count fecham a conta
O campo chunk_size da API do TikTok tem piso de 5 MB, teto de 64 MB, chunk final de 128 MB e um total_chunk_count que arredonda para baixo.

