Skip to content

Referência da API

A API REST do GoShip cobre organizações, projetos, ambientes, clusters, apps, bancos, domínios e volumes. O CLI usa exatamente esses endpoints.

  • Base URL: https://api.goship.sh/api/v1
  • OpenAPI / Swagger: em breve

A autenticação é via bearer token — veja API → Autenticação.

Organizações, ambientes e projetos

Os recursos vivem dentro de um projeto e de um ambiente, então os caminhos têm a forma /orgs/{org}/projects/{project}/environments/{env}/..., com o slug do ambiente (production, staging…) em {env}. Isso vale pra apps, databases, services, volumes, plans e available-plans.

curl -H "Authorization: Bearer $GOSHIP_TOKEN" \
  https://api.goship.sh/api/v1/orgs/acme/projects/loja/environments/production/apps

available-plans aceita ?kind=app ou ?kind=database e lista os planos que o ambiente oferece, conforme o cluster dele. Ambientes e clusters são da organização, não de um projeto: as rotas deles estão abaixo.

Projetos

MétodoCaminhoO que faz
GET/orgs/{org}/projectsLista os projetos que você alcança
POST/orgs/{org}/projectsCria um projeto — corpo {"name": "Loja", "slug": "loja"}; o slug é opcional e, sem ele, sai do nome
GET/orgs/{org}/projects/{project}Detalhes de um projeto
PATCH/orgs/{org}/projects/{project}Atualiza o projeto — corpo {"name": "...", "slug": "..."}, os dois opcionais; o slug do default não muda
DELETE/orgs/{org}/projects/{project}Apaga o projeto (o default não pode ser apagado)
GET/orgs/{org}/projects/{project}/membersPessoas do projeto, com o papel de cada uma
PUT/orgs/{org}/projects/{project}/members/{userID}Dá ou muda o papel — corpo {"role": "admin|developer|viewer"}
DELETE/orgs/{org}/projects/{project}/members/{userID}Tira a pessoa do projeto

Os papéis na API são admin (administrador), developer (desenvolvedor) e viewer (leitor), como aparecem no painel.

O slug segue ^[a-z]([a-z0-9-]{0,29}[a-z0-9])?$ e não pode ser new, settings, members, projects nem o slug de um ambiente de partida (production, staging, development).

Ambientes

Os ambientes são da organização. Veja Ambientes pras regras do slug e pro que cada escolha significa.

MétodoCaminhoO que faz
GET/orgs/{org}/environmentsLista os ambientes da organização, com o cluster e o servidor de banco de cada um
POST/orgs/{org}/environmentsCria um ambiente — corpo {"name": "QA", "slug": "qa", "cluster_id": "<id>", "db_server_id": "<id>"}; cluster_id e db_server_id são opcionais, e sem eles o ambiente usa o cluster GoShip e o PostgreSQL do GoShip
GET/orgs/{org}/environments/{env}Detalhes de um ambiente
PATCH/orgs/{org}/environments/{env}Muda o ambiente — corpo com qualquer destes campos: name, slug, cluster_id, db_server_id, is_default, position
DELETE/orgs/{org}/environments/{env}Apaga o ambiente (o padrão não pode ser apagado)

Só o dono e os administradores da organização criam, mudam e apagam ambientes.

A resposta do PATCH traz kept, uma lista de {project, cluster}: os projetos que já tinham app, banco ou volume no ambiente e ficaram no cluster em que estavam quando você trocou o cluster_id. Esses projetos seguem fixados até os recursos serem recriados no destino. A lista vem vazia quando nenhum ficou pra trás.

O DELETE responde 409 enquanto algum projeto tem app, banco ou volume no ambiente, e o corpo lista quais projetos seguram algo.

Clusters

Os clusters também são da organização. Veja Clusters.

MétodoCaminhoO que faz
GET/orgs/{org}/clustersLista os clusters que a organização pode usar; shared marca o cluster GoShip, compartilhado
POST/orgs/{org}/clustersCria um cluster: na sua nuvem, num servidor por SSH ou a partir de um kubeconfig (type: kubernetes)
GET/orgs/{org}/clusters/{id}Detalhes de um cluster, com o andamento das etapas
DELETE/orgs/{org}/clusters/{id}Remove o cluster; nos criados na sua nuvem, pode destruir a máquina também (Remover um cluster)

O DELETE responde 409 enquanto algum ambiente aponta pro cluster (o corpo lista os ambientes) ou algum projeto ainda roda algo nele.

Quatro rotas abaixo de /orgs/{org}/clusters/{id} cuidam do resto da vida do cluster:

MétodoCaminhoO que faz
GET/orgs/{org}/clusters/{id}/sizesOs tamanhos pra que o cluster pode ser redimensionado
POST/orgs/{org}/clusters/{id}/resizeMuda o tamanho — corpo {"size": "<slug>"}; veja Mudar o tamanho de um cluster
GET/orgs/{org}/clusters/{id}/resize/accessDiz se a conta de nuvem conectada ainda permite redimensionar (parar, iniciar e mudar a máquina)
POST/orgs/{org}/clusters/{id}/volumesLiga os volumes num cluster seu; veja Volumes

Ambientes de um projeto

MétodoCaminhoO que faz
GET/orgs/{org}/projects/{project}/environmentsOs ambientes do projeto, com o cluster que ele usa em cada um e se está fixado
PATCH/orgs/{org}/projects/{project}/environments/{env}Fixa o projeto, nesse ambiente, a outro cluster — corpo {"cluster_id": "<id>"}; só enquanto o projeto não tem nada no ambiente

Apps privados

Caminhos abaixo de /orgs/{org}/projects/{project}/environments/{env}/apps/{app}. Veja Apps privados.

MétodoCaminhoO que faz
PUT/visibilityMuda a visibilidade — corpo {"visibility": "private"} (ou "public")
GET/access/usersLista as pessoas com acesso
POST/access/usersAdiciona alguém — corpo {"username": "ana", "password": "opcional"}; a senha só volta na resposta quando foi gerada
PUT/access/users/{user}Troca a senha — corpo {"password": "opcional"}
DELETE/access/users/{user}Remove a pessoa e encerra a sessão dela
GET/access/token?reveal=1Token de automação; sem reveal, o valor fica oculto
POST/access/token/rotateGera um token novo e invalida o anterior

Para criar o app já privado, envie "private": true no corpo de POST /orgs/{org}/projects/{project}/environments/{env}/apps.

Convites e papéis

Os convites são criados com POST /orgs/{org}/invitations. O papel na organização é admin, member ou collaborator; projects é opcional e dá um papel (admin, developer ou viewer) por projeto. Colaborador exige pelo menos um projeto:

{
  "email": "carla@example.com",
  "role": "collaborator",
  "projects": [{"slug": "app-mobile", "role": "developer"}]
}

GET /auth/me devolve, além do usuário, a lista projects com o seu papel efetivo em cada projeto e a lista environments, com os ambientes de cada organização dele: [{"org": "acme", "slug": "staging", "name": "Staging", "is_default": false}].

O que as respostas trazem

  • GET /orgs: cada organização ganha default_environment, o ambiente padrão dela.
  • Um app (e as listas de apps) ganha environment, o slug do ambiente, e cluster, com {id, name, shared}: o cluster onde ele roda.
  • GET /auth/me: a lista environments, descrita acima.

Caminhos antigos

Os caminhos por projeto, sem ambiente, continuam respondendo por mais uma versão, como aliases do ambiente padrão da organização: /orgs/{org}/projects/{project}/apps, /databases, /services, /volumes, /plans e /available-plans. Cada resposta traz Deprecation: true e Link: <novo caminho>; rel="successor-version". Migre pro caminho com /environments/{env}.

Os caminhos que não têm mais correspondência respondem 410 Gone, com o corpo {"error": "this route moved", "code": "route_moved", "successor": "<caminho>"}, e o successor aponta o caminho novo:

Caminho que saiuNo lugar
/orgs/{org}/projects/{project}/nodes…os clusters da organização, em /orgs/{org}/clusters
o caminho do projeto que decidia onde os apps novos rodavamo cluster de cada ambiente, em /orgs/{org}/environments
/orgs/{org}/projects/{project}/cloud-accounts… e /orgs/{org}/projects/{project}/database-servers…as contas de nuvem e os servidores de banco são da organização: /orgs/{org}/cloud-accounts e /orgs/{org}/database-servers
/orgs/{org}/cloud-accounts/{id}/movea conta de nuvem é da organização, não de um projeto, então não há o que mover entre projetos

Erros

Os erros chegam com o status HTTP que diz a classe do problema e um corpo {"error": "...", "code": "..."}. O code é o motivo estável: decida por ele, nunca pelo texto de error, que pode mudar. A lista completa está em Códigos de erro.

  • 409 com code: in_use: o pedido conflita com o que existe, e o corpo lista o que bloqueia: os projetos que ainda têm recursos num ambiente que você quer apagar, ou os ambientes que ainda apontam pra um cluster que você quer remover.
  • 502 com code: platform_error: a plataforma por baixo falhou, e a mensagem diz a etapa e o cluster onde aconteceu.
  • 410 com code: route_moved: o caminho saiu do ar; o corpo traz o successor (veja a tabela acima).

Deploy, logs e comandos

Operações que duram o tempo que o trabalho durar respondem com um stream de eventos: Content-Type: application/x-ndjson, um objeto JSON por linha.

MétodoCaminhoO que faz
GET/orgs/{org}/projects/{project}/environments/{env}/apps/{app}/deploysHistórico de releases (JSON comum, não é stream)
POST/orgs/{org}/projects/{project}/environments/{env}/apps/{app}/deploysFaz build e release a partir de um .tar.gz do código
POST/orgs/{org}/projects/{project}/environments/{env}/apps/{app}/deploys/rollbackVolta pra uma versão anterior — corpo {"version": "v12"}
GET/orgs/{org}/projects/{project}/environments/{env}/apps/{app}/logsLogs — lines, follow, source, unit
POST/orgs/{org}/projects/{project}/environments/{env}/apps/{app}/runComando avulso — corpo {"command": "...", "once": true}
GET/orgs/{org}/projects/{project}/environments/{env}/apps/{app}/shellShell interativo por websocket — unit, isolated, width, height, term; mensagens de texto com os bytes do terminal nos dois sentidos

Eventos

{"type":"output","data":"---> building\n"}
{"type":"log","date":"2026-09-19T12:00:00Z","source":"web","unit":"...","message":"..."}
{"type":"ping"}
{"type":"result","ok":false,"error":"deploy failed: main.go:3: undefined: x","code":"deploy_failed"}
  • output é o texto da operação, na ordem em que sai.
  • ping só mantém a conexão viva; ignore.
  • result é sempre a última linha. O status HTTP 200 sai antes do trabalho começar, então quem diz se deu certo é o result. Um result de falha traz o code, como qualquer erro da API. Um stream que termina sem result foi interrompido — trate como falha.

Recusas que acontecem antes do trabalho começar (app inexistente, app pausada, arquivo grande demais) chegam como status HTTP normal com {"error": "...", "code": "..."}.

Deploy

O corpo é multipart/form-data: os campos de texto opcionais message e dockerfile, e por último o arquivo file, um tarball gzip do código. file precisa ser o último campo — o arquivo é repassado enquanto chega. Limite: 100 MB.

tar -czf app.tgz -C ./meu-app .
curl -N -X POST https://api.goship.sh/api/v1/orgs/acme/projects/loja/environments/production/apps/blog/deploys \
  -H "Authorization: Bearer $GOSHIP_TOKEN" \
  -F 'message=corrige o título' -F 'file=@app.tgz'

Fechar a conexão não cancela o deploy: o release segue até o fim e fica registrado no histórico com o resultado real. Você perde só a saída ao vivo.

Limites

Até 8 streams abertos por usuário ao mesmo tempo (deploys, comandos e logs com follow). O nono recebe 429.