Integrations API
Integrations come in two flavors: the GitHub App (which powers private-repo deploys, repo/branch listing, and push-to-deploy) and marketplace integrations (Sentry, Resend, Stripe, and more) that inject env vars into your projects. Credentials are encrypted at rest and never returned raw — reads surface only a masked hint.
Concept guide: Integrations overview.
All routes require authentication except the GitHub events webhook, which verifies an HMAC signature.
GitHub App
Section titled “GitHub App”Connection status
Section titled “Connection status”GET /v1/integrations/github/connection
Auth: any member. Response (IntegrationConnection): { connected, type, installationId, username }.
Authorize (save installation)
Section titled “Authorize (save installation)”POST /v1/integrations/github/authorize
Saves a GitHub App installation_id for the org (the connect flow’s completion step).
Auth: member. Body (AuthorizeGithubInput): { installationId } (coerced positive int). Response: IntegrationConnection.
curl -X POST https://api.pandastack.io/v1/integrations/github/authorize \ -H "Authorization: Bearer $PANDASTACK_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "installationId": 12345678 }'List repositories
Section titled “List repositories”GET /v1/integrations/github/repositories
Repos accessible via the installation token.
Auth: any member. Response: GithubRepo[] — each { fullName ('owner/repo'), private, defaultBranch }.
List branches
Section titled “List branches”GET /v1/integrations/github/branches
Auth: any member. Query: ?repo=owner/repo. Response: GithubBranch[] — each { name, commitSha }.
curl "https://api.pandastack.io/v1/integrations/github/branches?repo=acme/my-app" \ -H "Authorization: Bearer $PANDASTACK_TOKEN"Remove the GitHub integration
Section titled “Remove the GitHub integration”DELETE /v1/integrations/github/:installationId
Auth: member. Response: { removed: true }.
Marketplace catalog
Section titled “Marketplace catalog”Browse the catalog
Section titled “Browse the catalog”GET /v1/integrations/catalog
The marketplace catalog: categories, kinds, and entries.
Auth: any member. Response (IntegrationCatalog): { categories: string[], kinds: string[], entries: CatalogEntry[] }.
CatalogEntry:
| Field | Type | Notes |
|---|---|---|
id | string | |
name | string | |
category | string | |
kind | Native | External | |
status | live | coming_soon | |
connectionType | api_key | |
provisions | boolean | Optional; whether connecting provisions a resource. |
description | string | |
color | string | |
iconUrl | string | null | |
website | string | |
envVars | string[] | Env vars this integration injects. |
inputFields | CatalogInputField[] | Optional; each { key, label, placeholder?, type (text|password), required, hint? }. |
All connected statuses
Section titled “All connected statuses”GET /v1/integrations/statuses
All connected integration statuses (masked).
Auth: any member. Response (IntegrationStatuses): a record keyed by integration type, each value an IntegrationStatus.
Single integration status
Section titled “Single integration status”GET /v1/integrations/:type/status
Auth: any member. Response (IntegrationStatus): { type, connected, maskedKey, metadata, connectedAt }.
Connect & link
Section titled “Connect & link”Connect an integration
Section titled “Connect an integration”POST /v1/integrations/:type/connect
Connect a third-party integration — the credential is validated then encrypted.
Auth: member. Body (ConnectIntegrationInput):
| Field | Type | Required | Notes |
|---|---|---|---|
apiKey | string | no | Trimmed. The provider credential. |
metadata | record<string,string> | no | Extra fields from the catalog inputFields. |
Response: IntegrationStatus.
curl -X POST https://api.pandastack.io/v1/integrations/sentry/connect \ -H "Authorization: Bearer $PANDASTACK_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "apiKey": "sntrys_xxx", "metadata": { "org": "acme" } }'Disconnect an integration
Section titled “Disconnect an integration”DELETE /v1/integrations/:type/disconnect
Auth: member. Response: { removed: true }.
List linked projects
Section titled “List linked projects”GET /v1/integrations/:type/projects
Projects linked to an integration.
Auth: any member. Response: LinkedProject[] — each { projectId, name, slug, envVars, redeployed }.
Link an integration to projects
Section titled “Link an integration to projects”POST /v1/integrations/:type/link-projects
Links the integration to one or more projects — injects env vars and best-effort redeploys.
Auth: member. Body (LinkProjectsInput): { projectIds } — array of positive ints, min 1. Response (LinkProjectsResult): { linked: LinkedProject[] }.
curl -X POST https://api.pandastack.io/v1/integrations/sentry/link-projects \ -H "Authorization: Bearer $PANDASTACK_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "projectIds": [812, 900] }'Unlink from a project
Section titled “Unlink from a project”DELETE /v1/integrations/:type/unlink/:projectId
Auth: member. Response: { removed: true }.
GitHub events webhook
Section titled “GitHub events webhook”POST /api/v1/webhook/github-events
Receives GitHub App events. It is not token-authenticated — it verifies the x-hub-signature-256 header (HMAC-SHA256, timing-safe compare over the raw body) and reads x-github-event. Configure this as your GitHub App webhook URL; do not call it yourself.
A recognized event (for example a push on a tracked branch) triggers a deploy of the matching project. It responds fast (200) and is not wrapped in the standard envelope:
{ "success": true }An event that does not map to any action returns:
{ "success": true, "handled": false }Related
Section titled “Related”- Projects API — create private-repo projects once GitHub is connected.
- Billing API — Stripe webhook — the other signature-verified receiver.
- Environment variables & secrets — how linked integration env vars appear on a project.