Amba

Promotion

Export a project's declarative configuration bundle and import it into another project.

Cross-environment promotion: assemble a declarative configuration bundle from one project and apply it to another. Bundles carry configuration only — no secrets, no per-user data. See the Environment Promotion guide for the workflow and the full list of sections a bundle contains.

Both endpoints are project-scoped and require a developer PAT (Authorization: Bearer).

Endpoints

MethodPathDescription
GET/admin/projects/:projectId/promotion/exportAssemble a declarative bundle from this project.
POST/admin/projects/:projectId/promotion/importApply a bundle to this project.

GET /admin/projects/:projectId/promotion/export

Returns a bundle of the project's reusable configuration. Each section is included only if the project has authored entities of that type. The bundle is stamped with an exported_at timestamp and a version.

Response 200

{
  "data": {
    "version": 1,
    "exported_at": "2026-05-30T12:00:00.000Z",
    "currencies": [{ "key": "coins", "name": "Coins", "...": "..." }],
    "achievements": [{ "key": "first_workout", "...": "..." }],
    "collections": [{ "name": "questions", "columns": [], "indexes": [] }],
    "integrations": {
      "source_project_id": "00000000-0000-0000-0000-000000000000",
      "items": [
        {
          "provider": "apns",
          "config": {
            "apns_env": "production",
            "apns_team_id": "TEAM12345",
            "apns_key_id": "KEYID12345",
            "bundle_id": "com.example.app"
          },
          "credentials": "stripped"
        }
      ]
    }
  }
}

The integrations section carries each active integration's non-secret config only — push settings like the bundle id, team/key ids, and environment travel; .p8 keys, service-account JSON, and provider API keys never do. Every item is marked credentials: "stripped". source_project_id lets a later import copy the credentials server-side (see below).

Errors

  • 422 UNMAPPABLE_COLUMN_TYPE — a collection column uses a type the bundle format can't represent. error.message names the column.
  • 500 EXPORT_FAILED.

POST /admin/projects/:projectId/promotion/import

Apply a bundle to the target project. The bundle version must match the server's supported version (1).

Request

FieldTypeRequiredDescription
bundleobjectyesA bundle as produced by export. Must include a version.
modestringno"skip_existing" (default) leaves existing keys untouched; "merge" updates them.
include_integration_credentialsbooleannoCopy integration credentials server-side from the bundle's source project and activate the integrations. Same-developer projects only.

Integrations: pending vs. copied credentials

Bundles never carry credential material, so an imported integration needs its credentials one of two ways:

  • Default (no flag). Each integration is created inactive in a pending_credentials state (config.credentials_status: "pending"). Upload the credentials with POST /admin/projects/:projectId/integrations (or the amba_integrations_configure MCP tool) — that call stores the credential in the project's credential store and activates the integration. The import response's integrations array repeats this guidance per provider.
  • include_integration_credentials: true. When the bundle's integrations.source_project_id and the target project belong to the same developer, the stored credentials are copied directly between the two projects' credential stores — entirely server-side, never through the client — and the integrations activate immediately. A cross-developer attempt is refused with 403 INTEGRATION_CREDENTIALS_FORBIDDEN (drop the flag to import as pending_credentials instead).

In merge mode an integration that already exists on the target keeps its working credentials and active state — only the non-secret fields are refreshed (unless the flag re-copies credentials from the source).

Response 200

A per-section summary of what was created, updated, or skipped, plus a per-integration status when the bundle has an integrations section:

{
  "data": {
    "mode": "skip_existing",
    "summary": {
      "currencies": { "created": 2, "updated": 0, "skipped": 1 },
      "achievements": { "created": 8, "updated": 0, "skipped": 0 },
      "integrations": { "created": 2, "updated": 0, "skipped": 0 }
    },
    "integrations": [
      { "provider": "apns", "status": "activated" },
      {
        "provider": "revenuecat",
        "status": "pending_credentials",
        "guidance": "Credential material never travels in a bundle, so the revenuecat integration was created inactive..."
      }
    ]
  }
}

Integration statuses: activated (created with copied credentials), updated (existing row refreshed), pending_credentials (created inactive, awaiting a credential upload — guidance names the exact call), skipped.

Errors

  • 400 INVALID_JSON — request body wasn't valid JSON.
  • 400 INVALID_BUNDLE — body is missing the bundle object, or include_integration_credentials was set on a bundle without integrations.source_project_id.
  • 400 UNSUPPORTED_BUNDLE_VERSION — the bundle's version isn't supported (expected 1).
  • 400 INVALID_MODEmode is neither merge nor skip_existing.
  • 400 INVALID_FLAGinclude_integration_credentials is not a boolean.
  • 400 INVALID_IDENTIFIER — a collection in the bundle has an invalid table / column name.
  • 400 INVALID_COLLECTION_SCHEMA — a collection schema in the bundle is malformed.
  • 400 INVALID_INTEGRATIONS_SECTION — the bundle's integrations section is malformed or names an unknown provider.
  • 403 INTEGRATION_CREDENTIALS_FORBIDDENinclude_integration_credentials was set but the bundle's source project and the target don't belong to the same developer.
  • 503 INTEGRATION_CREDENTIALS_COPY_FAILED — the credential store was unavailable mid-copy. The import is idempotent: re-run it, or drop the flag to land the integrations as pending_credentials.
  • 500 IMPORT_FAILED.

MCP tools

ToolDescription
amba_project_exportExport this project's configuration bundle.
amba_project_importImport a configuration bundle into this project.

On this page