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/appsavailable-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étodo | Caminho | O que faz |
|---|---|---|
GET | /orgs/{org}/projects | Lista os projetos que você alcança |
POST | /orgs/{org}/projects | Cria 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}/members | Pessoas 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étodo | Caminho | O que faz |
|---|---|---|
GET | /orgs/{org}/environments | Lista os ambientes da organização, com o cluster e o servidor de banco de cada um |
POST | /orgs/{org}/environments | Cria 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étodo | Caminho | O que faz |
|---|---|---|
GET | /orgs/{org}/clusters | Lista os clusters que a organização pode usar; shared marca o cluster GoShip, compartilhado |
POST | /orgs/{org}/clusters | Cria 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étodo | Caminho | O que faz |
|---|---|---|
GET | /orgs/{org}/clusters/{id}/sizes | Os tamanhos pra que o cluster pode ser redimensionado |
POST | /orgs/{org}/clusters/{id}/resize | Muda o tamanho — corpo {"size": "<slug>"}; veja Mudar o tamanho de um cluster |
GET | /orgs/{org}/clusters/{id}/resize/access | Diz se a conta de nuvem conectada ainda permite redimensionar (parar, iniciar e mudar a máquina) |
POST | /orgs/{org}/clusters/{id}/volumes | Liga os volumes num cluster seu; veja Volumes |
Ambientes de um projeto
| Método | Caminho | O que faz |
|---|---|---|
GET | /orgs/{org}/projects/{project}/environments | Os 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étodo | Caminho | O que faz |
|---|---|---|
PUT | /visibility | Muda a visibilidade — corpo {"visibility": "private"} (ou "public") |
GET | /access/users | Lista as pessoas com acesso |
POST | /access/users | Adiciona 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=1 | Token de automação; sem reveal, o valor fica oculto |
POST | /access/token/rotate | Gera 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 ganhadefault_environment, o ambiente padrão dela.- Um app (e as listas de apps) ganha
environment, o slug do ambiente, ecluster, com{id, name, shared}: o cluster onde ele roda. GET /auth/me: a listaenvironments, 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 saiu | No 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 rodavam | o 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}/move | a 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.
409comcode: 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.502comcode: platform_error: a plataforma por baixo falhou, e a mensagem diz a etapa e o cluster onde aconteceu.410comcode: route_moved: o caminho saiu do ar; o corpo traz osuccessor(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étodo | Caminho | O que faz |
|---|---|---|
GET | /orgs/{org}/projects/{project}/environments/{env}/apps/{app}/deploys | Histórico de releases (JSON comum, não é stream) |
POST | /orgs/{org}/projects/{project}/environments/{env}/apps/{app}/deploys | Faz build e release a partir de um .tar.gz do código |
POST | /orgs/{org}/projects/{project}/environments/{env}/apps/{app}/deploys/rollback | Volta pra uma versão anterior — corpo {"version": "v12"} |
GET | /orgs/{org}/projects/{project}/environments/{env}/apps/{app}/logs | Logs — lines, follow, source, unit |
POST | /orgs/{org}/projects/{project}/environments/{env}/apps/{app}/run | Comando avulso — corpo {"command": "...", "once": true} |
GET | /orgs/{org}/projects/{project}/environments/{env}/apps/{app}/shell | Shell 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.pingsó mantém a conexão viva; ignore.resulté sempre a última linha. O status HTTP200sai antes do trabalho começar, então quem diz se deu certo é oresult. Umresultde falha traz ocode, como qualquer erro da API. Um stream que termina semresultfoi 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.