Pular para o conteúdo
FreshApp Demo

DOCUMENTAÇÃO PARA DESENVOLVEDORES

Documentação da API de geração

Com a API de geração, crie gerações com os modelos do site a partir do seu próprio código. Uma requisição informa um modelo e a entrada dele; a resposta é uma geração que você acompanha até terminar, e os arquivos dela são baixados deste site. Os modelos, preços, limites e códigos de erro desta página são os que estão valendo agora.

Criar gerações pela API exige um pacote de créditos pago ou uma assinatura paga ativa, e gasta apenas créditos pagos. Consultar, listar e baixar funcionam com qualquer chave da conta.

Início rápido

Crie uma chave na página de chaves de API, guarde-a no seu servidor e defina-a como API_KEY. Os exemplos criam uma geração com seed-audio-1.0, consultam até ela terminar e baixam o primeiro arquivo.

Envie uma Idempotency-Key nova a cada nova requisição. Quando uma requisição ficar sem resposta, envie de novo com a mesma chave e o mesmo corpo: você recebe a geração que a primeira requisição criou e paga uma vez só.

cURL

export API_ORIGIN='https://demo.freshapp.ai'
export API_KEY='sk_YOUR_API_KEY'

curl --fail-with-body "$API_ORIGIN/api/v1/generations" \
  -H "Authorization: Bearer $API_KEY" \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: order-1001' \
  -d '{"model":"seed-audio-1.0","input":{"prompt":"Um farol em um penhasco ao amanhecer, mar calmo, luz suave."}}'

# Read it every 5 to 10 seconds until its status ends.
curl --fail-with-body "$API_ORIGIN/api/v1/generations/GENERATION_ID" \
  -H "Authorization: Bearer $API_KEY"

# A delivered output's url is a signed link: no key needed.
curl --fail-with-body -o result "OUTPUT_URL"

Cliente TypeScript

import { createClient } from './open-api-client';

const client = createClient({
  baseUrl: "https://demo.freshapp.ai",
  apiKey: process.env.API_KEY, // on your server only
});
const generation = await client.create(
  {
    "model": "seed-audio-1.0",
    "input": {
      "prompt": "Um farol em um penhasco ao amanhecer, mar calmo, luz suave."
    }
  },
  { idempotencyKey: "order-1001" }
);
const done = await client.wait(generation.id);
for (const output of done.outputs)
  if (output.status === 'delivered') {
    const file = await client.download(output);
    // file.body is the output, as output.content_type says
  }

Hook do React

import { createClient } from './open-api-client';
import { useGeneration } from './open-api-react';

// In a browser on this site: no key, the visitor's own session.
const client = createClient();

export function Progress({ id }: { id: string }) {
  const { generation, error, done } = useGeneration(client, id);
  if (error) return <p>{String(error)}</p>;
  return <p>{generation?.status ?? '…'}{done ? ' ✓' : ''}</p>;
}

Chaves e permissões

Toda requisição leva Authorization: Bearer com uma chave da página de chaves de API. Uma chave é sk_ seguido de 43 letras, dígitos, hifens ou sublinhados, e aparece uma única vez, quando é criada ou girada. Uma requisição com Authorization é avaliada só pela chave, nunca por uma sessão conectada ao lado.

Uma chave só lê (lista, consulta e baixa) ou também pode gerar (cria e cancela). Uma chave só de leitura recebe 403 insufficient_scope quando tenta criar ou cancelar, e nada é gravado.

Uma chave pode ter uma lista de IPs permitidos com endereços e redes: de qualquer outro endereço ela recebe 403 ip_not_allowed. Dar mais permissão a uma chave, aumentar um limite ou ampliar a lista exige um login recente; restringir, nunca.

Girar uma chave dá a ela um valor novo na hora, e o antigo para de funcionar. Revogar uma chave a encerra de vez: as gerações dela ainda não enviadas a um modelo são canceladas e os créditos voltam, e as que já estão em andamento terminam.

Só contas com acesso pago criam gerações pela API (senão, 403 not_eligible), e a API gasta apenas créditos pagos (402 insufficient_credits). Créditos de presente e de check-in ficam para o site.

Endpoints da API de geração

Todos os caminhos ficam neste site. Os corpos de requisição e de resposta são JSON, exceto os arquivos de resultado.

https://demo.freshapp.ai

MétodoCaminhoPermissãoO que faz
POST/api/v1/generationsgenerations:writeCria uma geração. Exige uma Idempotency-Key; responde 202 com a geração.
GET/api/v1/generationsgenerations:readAs gerações da conta, da mais recente para a mais antiga, uma página por vez (limit, cursor, module). Gerações de texto só são consultadas pelo id.
GET/api/v1/generations/{id}generations:readUma geração da conta, com as saídas, os créditos e o motivo do fim.
POST/api/v1/generations/{id}/cancelgenerations:writeCancela uma geração ainda não enviada ao modelo e devolve os créditos.
GET, HEAD/api/media/{id}generations:read (ou um link assinado)O arquivo de uma saída, com no máximo um intervalo de bytes. Um link assinado dispensa a chave e funciona de qualquer endereço.

Modelos e preços

Os modelos ativados neste site, do jeito que a API os aceita: use o id como model e os campos como input. Uma requisição reserva o resultado mais caro ao ser criada; quando termina, você paga o que foi entregue.

Id do modeloNomeTipoPreçoMáximo por requisiçãoCampos de entrada
seed-audio-1.0Seed Audio 1.0Áudio75 créditos por minuto; no mínimo 10 por um resultado entregue150 créditosprompt (obrigatório), voice, audio_references, image_url, output_format, sample_rate, speed, volume, pitch, multilingual

Idempotência

Criar uma geração exige um cabeçalho Idempotency-Key de 1 a 128 letras, dígitos, pontos, dois-pontos, sublinhados ou hifens. Use um id do seu próprio sistema, como um número de pedido, para que o mesmo trabalho sempre tenha a mesma chave.

A mesma chave com a mesma requisição devolve a mesma geração, não importa quantas vezes seja enviada, e é cobrada uma vez. A mesma chave com outra requisição dá 409 idempotency_conflict, e nada é criado.

Um tempo esgotado ou uma conexão caída não significa que a requisição falhou. Envie de novo com a mesma chave e o mesmo corpo, e guarde os dois até ter uma resposta. Um 5xx, um 429 ou um 408 são tratados do mesmo jeito: espere o que o Retry-After disser e reenvie a requisição sem mudanças.

Status e consultas

Consulte uma geração com GET /api/v1/generations/{id} a cada 5 segundos no começo e depois até a cada 10 segundos, até o status ser final. Um 429 informa no Retry-After quando consultar de novo.

StatusSignificado
queuedAceita e aguardando envio ao modelo. Ainda pode ser cancelada.
processingEnviada ao modelo, ou os arquivos dela estão sendo salvos e liquidados.
succeededTodas as saídas foram entregues e os créditos estão liquidados.
partially_succeededAlgumas saídas foram entregues e cobradas; os créditos das outras voltaram.
failedNada foi entregue; error diz o motivo, e os créditos reservados voltaram.
canceledCancelada antes do envio, por você ou porque a chave foi revogada; os créditos voltaram.

billing.reserved_credits é o que a criação reservou. Depois da liquidação, charged_credits é o que você pagou e refunded_credits o que voltou; até lá, os dois são null e held_credits mostra o que está reservado.

Uma geração que aguarda uma verificação manual mostra review com a hora em que a verificação começou, e mantém os créditos até ela terminar; depois, segue em frente ou os créditos voltam.

Arquivos de resultado

Cada saída entregue tem uma url neste site. Para uma chave, é um link assinado que funciona por uma hora sem a chave e de qualquer endereço, então você pode passá-lo a uma ferramenta de download. Depois de uma hora, consulte a geração de novo para receber um link novo.

Com a própria chave, GET /api/media/{id} também devolve o arquivo, dentro da lista de IPs da chave. Os dois aceitam HEAD e um intervalo de bytes (Range: bytes=0-1023), e nunca redirecionam para outro site.

Um arquivo citado em uma entrada, como uma amostra de áudio ou uma imagem, precisa ter sido enviado por esta conta no site, ser uma das amostras do site ou um link de uma fonte que o site permite; qualquer outra coisa é recusada antes de reservar créditos.

Limites

Cada limite abaixo é o que este site aplica agora, e cada recusa diz qual foi atingido.

  • Uma requisição reserva no máximo 150 créditos, a requisição mais cara dos modelos ativados. Uma chave pode ter um limite menor, e o max_credits de uma requisição baixa o limite para ela; acima disso, a resposta é 400 request_limit_exceeded.
  • Cada chave gasta no máximo 5.000 créditos por dia UTC, a menos que você defina o limite dela, até 1.000.000; acima disso, a chave recebe 429 key_daily_limit_exceeded até o próximo dia UTC.
  • Todas as chaves de uma conta, com os clientes de IA dela, gastam no máximo 10.000 créditos por dia UTC, a menos que você defina o limite da conta; acima disso, a resposta é 429 account_daily_limit_exceeded.
  • Cada chave e cada conta envia no máximo 20 criações e cancelamentos e 240 consultas e downloads por minuto; acima disso, 429 rate_limited com Retry-After.
  • No máximo 2 gerações de uma conta rodam ao mesmo tempo; outra espera com 429 too_many_active.
  • O corpo de uma requisição tem no máximo 32 KiB de JSON; um maior dá 413 request_too_large.

Códigos de erro

Um erro tem a forma {"error": {"code": …, "message": …}}. O código é sempre um destes, e a mensagem é em inglês, para desenvolvedores. Um 429 ou um 503 informa no Retry-After quantos segundos esperar. Uma geração que falhou ou foi cancelada traz no campo error um dos códigos marcados como de uma geração.

HTTPCódigoSignificadoO que fazer
401invalid_credentialA chave de API está ausente, malformada, é desconhecida, foi revogada ou substituída.Confira a chave de API, a permissão e a lista de IPs permitidos dela.
401credential_revokedA chave foi revogada ou girada durante a requisição; uma geração na fila de uma chave revogada é cancelada e os créditos voltam.Confira a chave de API, a permissão e a lista de IPs permitidos dela.
403insufficient_scopeA chave não pode fazer isto: o erro informa a permissão necessária em required_scope.Confira a chave de API, a permissão e a lista de IPs permitidos dela.
403ip_not_allowedA chave não pode ser usada deste endereço: ele está fora da lista de IPs permitidos da chave.Confira a chave de API, a permissão e a lista de IPs permitidos dela.
401unauthorizedA sessão do site terminou: entre de novo.Altere a requisição antes de reenviá-la.
403invalid_originUma requisição do site precisa vir do próprio site.Altere a requisição antes de reenviá-la.
403forbiddenA requisição chegou sem um endereço de cliente confiável.Fale com o suporte do site.
400invalid_requestA requisição está malformada: o JSON, os cabeçalhos (Idempotency-Key, Content-Type) ou a consulta.Altere a requisição antes de reenviá-la.
400invalid_inputA entrada não combina com os campos do modelo, ou o modelo não conseguiu usá-la.Altere a requisição antes de reenviá-la.
413request_too_largeO corpo da requisição é grande demais.Altere a requisição antes de reenviá-la.
409idempotency_conflictEsta Idempotency-Key já foi usada com outra requisição.Altere a requisição antes de reenviá-la.
404model_unavailableO modelo é desconhecido ou não está disponível agora.Altere a requisição antes de reenviá-la.
404not_foundNão existe esse caminho, geração ou arquivo para esta conta.Altere a requisição antes de reenviá-la.
405method_not_allowedO caminho não aceita este método; Allow lista os que ele aceita.Altere a requisição antes de reenviá-la.
409not_cancelableA geração já foi enviada ao modelo ou já terminou.Altere a requisição antes de reenviá-la.
409not_readyO arquivo ainda não está pronto.Espere o que o Retry-After disser e reenvie.
410expiredO arquivo passou do período de retenção e foi excluído.Altere a requisição antes de reenviá-la.
400request_limit_exceededA requisição custaria mais que o max_credits dela, ou que o limite por requisição da chave ou do site.Altere a requisição antes de reenviá-la.
403not_eligibleGerar pela API exige uma conta paga.Compre um pacote de créditos ou um plano: a API gasta apenas créditos pagos.
403email_unverifiedConfirme o e-mail da conta para gerar.Altere a requisição antes de reenviá-la.
402insufficient_creditsCréditos insuficientes: a API gasta apenas créditos pagos.Compre um pacote de créditos ou um plano: a API gasta apenas créditos pagos.
403generation_restrictedA geração está pausada para esta conta após recusas de conteúdo repetidas; ends_at diz até quando.Fale com o suporte do site.
403trial_pausedOs testes do site estão pausados para esta conta depois que várias saídas de teste passaram dos limites do teste; ends_at diz até quando. Pedidos sem teste seguem normalmente.Altere a requisição antes de reenviá-la.
429key_daily_limit_exceededO limite diário de gastos da chave foi atingido.Espere o que o Retry-After disser e reenvie. Retry-After: até o próximo dia UTC.
429account_daily_limit_exceededO limite diário de gastos da conta na API foi atingido.Espere o que o Retry-After disser e reenvie. Retry-After: até o próximo dia UTC.
429rate_limitedRequisições demais em pouco tempo.Espere o que o Retry-After disser e reenvie. Retry-After: a janela do limite.
429too_many_activeHá gerações demais da conta em andamento.Espere o que o Retry-After disser e reenvie. Retry-After: 30 s.
429too_many_under_reviewAlgumas gerações da conta aguardam uma verificação manual.Espere o que o Retry-After disser e reenvie. Retry-After: 3.600 s.
503busyHá gerações demais em andamento no site agora.Espere o que o Retry-After disser e reenvie. Retry-After: 30 s.
503pausedA geração está pausada no momento.Espere o que o Retry-After disser e reenvie. Retry-After: 60 s.
503temporarily_unavailableA requisição não pôde ser concluída agora.Reenvie a mesma requisição com a mesma Idempotency-Key. Retry-After: 60 s.
503api_unavailableA geração ainda não está disponível neste site.Espere o que o Retry-After disser e reenvie. Retry-After: 60 s.
503retryAlgo mudou durante a requisição, como as configurações da chave.Reenvie a mesma requisição com a mesma Idempotency-Key. Retry-After: 60 s.
503unavailableOs arquivos estão temporariamente indisponíveis.Espere o que o Retry-After disser e reenvie. Retry-After: 60 s.
500internal_errorAlgo deu errado no site.Reenvie a mesma requisição com a mesma Idempotency-Key.
400request_failedA requisição foi recusada por um motivo sem código próprio.Fale com o suporte do site.
400captcha_requiredConclua a verificação de segurança do site.Altere a requisição antes de reenviá-la.
403captcha_failedA verificação de segurança do site não passou.Altere a requisição antes de reenviá-la.
503captcha_unavailableA verificação de segurança do site está indisponível.Espere o que o Retry-After disser e reenvie. Retry-After: 60 s.
400reference_unavailableUm arquivo enviado e citado não existe mais ou não é desta conta.Altere a requisição antes de reenviá-la.
413reference_too_largeOs arquivos citados podem somar no máximo 10 MB.Altere a requisição antes de reenviá-la.
503reference_storage_unavailableO armazenamento dos arquivos citados está indisponível.Espere o que o Retry-After disser e reenvie. Retry-After: 60 s.
409storage_quota_exceededO armazenamento da conta está cheio.Fale com o suporte do site.
Em uma geraçãocanceledA geração foi cancelada antes do envio; os créditos voltaram.Altere a requisição antes de reenviá-la.
Em uma geraçãosubmission_expiredA geração não pôde ser enviada a tempo; os créditos voltaram.Reenvie a mesma requisição com a mesma Idempotency-Key.
Em uma geraçãomodel_busyO modelo estava ocupado; os créditos voltaram.Espere o que o Retry-After disser e reenvie.
Em uma geraçãocontent_rejectedAs verificações de segurança do conteúdo recusaram a entrada ou a saída.Altere a requisição antes de reenviá-la.
Em uma geraçãoresult_expiredO resultado não pôde ser salvo a tempo.Fale com o suporte do site.
Em uma geraçãogeneration_failedA geração falhou.Fale com o suporte do site.
Em uma geraçãodelivery_failedO resultado não pôde ser entregue; os créditos voltaram.Fale com o suporte do site.
Em uma geraçãotrial_limit_exceededA saída do teste do site passou dos limites do teste e não foi entregue; os créditos voltaram.Altere a requisição antes de reenviá-la.

Cliente TypeScript e hook do React

O cliente TypeScript, open-api-client.ts, não precisa de nenhum outro pacote e roda em servidores, workers e navegadores. Em um servidor, passe baseUrl e apiKey; em um navegador neste site, não passe nenhum dos dois, e as requisições usam a sessão do próprio visitante.

create envia uma Idempotency-Key, a sua ou um valor aleatório novo, e reenvia a mesma requisição depois de uma conexão caída, um 5xx, um 429 ou um 408, esperando o que o Retry-After disser. Quando desiste, o erro traz a chave, para você reenviar a requisição mais tarde. Com um store como o localStorage, uma requisição mantém a primeira chave ao recarregar a página.

wait consulta uma geração até ela terminar, a cada 5 segundos no começo e depois até 10, e para quando você a interrompe. download busca o arquivo de uma saída e só envia a chave para os links não assinados deste site.

O hook do React, open-api-react.ts, acompanha uma geração com o wait do cliente e para quando o componente é desmontado. Baixe os dois arquivos, deixe-os lado a lado e mude a extensão para .ts.

Downloads