Amba

Push Setup (APNs + FCM)

Configure APNs keys and FCM service-account credentials so Amba can deliver notifications to your users' devices.

Amba stores your APNs and FCM credentials encrypted, then loads them at send time. You configure them once per project; the rest is automatic.

What you need

iOS (APNs)

  1. An APNs Auth Key (.p8) from Apple Developer → Keys+, scope Apple Push Notifications service.
  2. The key's Key ID (10 characters, shown next to the key).
  3. Your Team ID (top right of Apple Developer).
  4. The app's bundle identifier (e.g. com.example.todoapp).

Android (FCM)

  1. A Firebase project linked to your app's package name.
  2. A service-account JSON with the Firebase Cloud Messaging API permission (Firebase console → Project settings → Service accounts → Generate new private key).
amba_integrations_configure({
  project_id: "proj_xxx",
  provider: "apns",
  config: {
    key_id: "ABC123DEFG",
    team_id: "TEAM123456",
    bundle_id: "com.example.todoapp",
    apns_key_p8: "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
    environment: "sandbox"
  }
})

amba_integrations_configure({
  project_id: "proj_xxx",
  provider: "fcm",
  config: {
    service_account_json: "{ ...the full Firebase service-account JSON... }"
  }
})

Configure via the Admin API

POST /admin/integrations
Authorization: Bearer <developer access token>
 
{
  "provider": "apns",
  "config": {
    "key_id": "ABC123DEFG",
    "team_id": "TEAM123456",
    "bundle_id": "com.example.todoapp",
    "apns_key_p8": "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
    "environment": "sandbox"
  }
}

Use "environment": "sandbox" for development / TestFlight / Xcode builds, and "production" for App Store releases. The server rejects sandbox tokens against the production APNs endpoint (and vice versa), so this flag matters. "development" is accepted as an alias for "sandbox".

Config fields

These are the only fields each provider accepts — the same names whether you call MCP or the Admin API.

APNs

FieldRequiredNotes
key_idyes10-char Apple Key ID.
team_idyes10-char Apple Team ID.
bundle_idyesYour app's bundle identifier.
environmentyes"sandbox" or "production" ("development""sandbox").
apns_key_p8yes*Full .p8 file contents. Stored as an encrypted secret; never returned.

FCM

FieldRequiredNotes
service_account_jsonyes*Full service-account JSON (string or object). The FCM project id is read from it. Stored as an encrypted secret; never returned.

* Pasting the credential inline is the recommended path — Amba stores it as an encrypted secret automatically. If you'd rather manage the secret yourself, set it first with amba_secrets_set and reference it instead: APNs accepts apns_key_secret_name (with key_id, team_id, bundle_id, environment); FCM accepts fcm_service_account_secret_name together with fcm_project_id. The credential material itself is never stored in the integration config either way.

Verify credentials

Once stored, trigger a POST /admin/integrations/:provider/test to validate credentials against the live provider before you try a real send:

POST /admin/integrations/apns/test
Authorization: Bearer <developer access token>

Response on success:

{ "data": { "provider": "apns", "valid": true } }

For APNs and FCM the test path deliberately sends to an invalid token — a 400-class response proves the credentials themselves are good. A 401 / 403 from the provider surfaces as { valid: false }. An infra-level failure (malformed PEM, credential load error) returns 502 CREDENTIAL_LOAD_FAILED so you can tell a bad key from a bad environment.

Register device tokens

Tokens come from the platform SDK. In Expo:

import { Amba } from '@layers/amba-expo';
 
// Register the device push token after Amba.configure() — opt-in;
// nothing prompts the user automatically:
const result = await Amba.registerPushToken();
// result is { token, platform } or null (permission denied / simulator / unsupported)

Under the hood the client SDK calls:

await client.push.registerToken(token, 'ios'); // or 'android'
// POST /client/push/tokens

Platform must be 'ios' or 'android'. The server infers the provider (apns / fcm) from the platform.

Send a test push

End-to-end validation — this sends a real notification through the same pipeline campaigns use.

POST /admin/push/test
 
{
  "title": "Test push",
  "body": "If you see this, push works.",
  "app_user_id": "<uuid>"
}

Or target an explicit token:

{
  "title": "Test push",
  "body": "...",
  "device_token": "abc123...",
  "provider": "apns"
}

On success you get { data: { sent: true, delivery_id, provider, provider_message_id } }. Provider-side failures surface as 502 with error.details.invalid_token so you can mark dead tokens.

Expo config plugin

You also need the iOS aps-environment entitlement. The @layers/amba-expo config plugin handles it:

{
  "expo": {
    "plugins": [
      [
        "@layers/amba-expo",
        { "projectId": "proj_...", "clientKey": "amba_ck_...", "scheme": "myapp" }
      ]
    ]
  }
}

Rebuild native after changing app.json (npx expo prebuild or npx expo run:ios). Push on iOS requires a development build — Expo Go cannot add custom entitlements.

Routes reference

MethodPathDescription
POST/admin/integrationsCreate / upsert APNs or FCM credentials
GET/admin/integrationsList configured integrations
PATCH/admin/integrations/:providerUpdate config or toggle is_active
POST/admin/integrations/:provider/testValidate credentials against the provider
POST/admin/push/testOne-off test push through the real stack
POST/client/push/tokensSDK-side token registration

Next

On this page