{
  "data": {
    "a": {
      "slug": "expo-push-notifications",
      "name": "Expo Push Notifications",
      "vendor": "Expo",
      "vendorUrl": "https://expo.dev",
      "kind": "http-api",
      "category": "notifications",
      "summary": "Hosted push service from Expo that takes one HTTPS request and relays it to Apple's APNs and Google's FCM for apps built with Expo. It issues push tickets and receipts, and sending is free.",
      "url": "https://www.anchorterminal.com/tools/expo-push-notifications",
      "markdownUrl": "https://www.anchorterminal.com/tools/expo-push-notifications.md",
      "slimMarkdownUrl": "https://www.anchorterminal.com/tools/expo-push-notifications.min.md",
      "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/expo-push-notifications.json",
      "repo": "https://github.com/expo/expo-server-sdk-node",
      "license": "Proprietary service under Expo's terms of service. The Node.js server SDK is MIT",
      "transports": [
        "http"
      ],
      "remoteUrl": "https://exp.host/--/api/v2/push/send",
      "packages": [
        {
          "registry": "npm",
          "name": "expo-server-sdk"
        }
      ],
      "auth": "mixed",
      "authNotes": "No credential by default. The docs say the API \"currently does not require any authentication\", and a send needs only an Expo push token. An owner can turn on enhanced push security in the EAS dashboard, after which every call needs `Authorization: Bearer \u003caccess token\u003e` or fails with `UNAUTHORIZED`. Tokens are personal access tokens, which act on everything the person can reach, or robot user tokens limited by role. Both are created and revoked by a person in the dashboard.",
      "pricing": "free",
      "pricingNotes": "Free. The push FAQ says there is no cost for sending through the service, and the pricing page lists no push charge. A send needs an Expo project with APNs and FCM credentials, which a person sets up on an Expo account. The Free plan is $0 a month, Starter $19 and Production $199, and those prices buy builds and updates, not push. Whether signup asks for a card was not stated.",
      "priceSummary": "Free",
      "where": "hosted",
      "x402": {
        "level": "no",
        "evidence": "No x402, MPP or L402 in the push docs, the pricing page or the Node SDK source (checked 2026-10-09).",
        "endpoints": []
      },
      "toolCount": null,
      "popularity": {
        "githubStars": 1037,
        "npmWeekly": 1348515,
        "pypiWeekly": null,
        "asOf": "2026-10-09"
      },
      "docsUrl": "https://docs.expo.dev/push-notifications/sending-notifications/",
      "llmsTxt": "https://docs.expo.dev/llms.txt",
      "capabilities": [
        "notify.push"
      ],
      "tags": [
        "hosted",
        "free",
        "push",
        "no-key",
        "llms-txt",
        "typescript",
        "closed-source",
        "status-page",
        "soc2"
      ],
      "lastRelease": "2026-08-24",
      "graded": true,
      "anchor": {
        "graded": true,
        "score": 58.8,
        "grade": "C",
        "agentReady": false,
        "rank": 571,
        "ranked": true,
        "rankOf": 950,
        "categoryRank": 9,
        "methodology": "0.4",
        "run": "2026-10-01",
        "scores": {
          "ergonomics": 63,
          "maintenance": 74,
          "payments": 40,
          "reliability": 65,
          "schema": 60,
          "security": 48,
          "transparency": 68
        },
        "pending": [
          "performance",
          "tasks"
        ],
        "assessment": {
          "confidence": "medium",
          "date": "2026-10-09"
        },
        "negative": 0,
        "verdict": "A free push relay with a small, well documented HTTP API, published limits of 600 notifications a second and written error codes. Sending needs no credential unless the owner turns on access tokens, there is no idempotency key or SLA, and the status page records three iOS push incidents since 4 August 2026.",
        "bestFor": "An agent that must push to an app already built with Expo, at no cost and with one call for both platforms.",
        "strengths": [
          "One POST to `https://exp.host/--/api/v2/push/send` reaches both APNs and FCM, with up to 100 messages a request",
          "Sending is free, per the push FAQ, and the Free plan costs $0 a month",
          "Limits are published. 600 notifications a second per project, 100 messages a request, 1,000 receipt IDs a request",
          "Docs are served as Markdown with an `llms.txt` index, and every message field is mapped to its APNs or FCM equivalent",
          "Expo states notification content is held only in memory and queues until handed to Apple or Google"
        ],
        "weaknesses": [
          "The send API needs no authentication by default, so anyone holding a push token can send to that device until the owner enables access tokens",
          "No idempotency key. Expo says a notification may reach Apple or Google more than once, or not at all",
          "No SLA for the push service, stated in the docs",
          "Three iOS push incidents on the status page since 4 August 2026, one a partial outage of 83 minutes and one a backlog of 4 hours 41 minutes",
          "No OpenAPI file or push API changelog was found, and only the Node.js SDK is maintained by Expo",
          "Expo's terms say accounts registered by bots, agents or other automated means are not permitted. This matters before any probe is run"
        ],
        "agentNotes": [
          "Send an array of up to 100 messages per request, all for one project, and stay under 600 notifications a second",
          "Keep each ticket `id` and POST them to `/--/api/v2/push/getReceipts` about 15 minutes later. Receipts are cleared after 24 hours",
          "Stop sending to a token when a ticket or receipt returns `DeviceNotRegistered`",
          "If the project has enhanced push security on, send `Authorization: Bearer \u003caccess token\u003e` or the call fails with `UNAUTHORIZED`",
          "Retry 429 and 5xx with exponential backoff, and expect an occasional duplicate because there is no idempotency key"
        ],
        "metrics": {
          "kind": "remote",
          "measured": false
        },
        "reviewCount": 0,
        "avgRating": 0,
        "history": [
          {
            "basis": "public evidence",
            "confidence": "medium",
            "grade": "C",
            "methodology": "0.4",
            "pending": [
              "performance",
              "tasks"
            ],
            "run": "2026-10-01",
            "runLabel": "October 2026 research run",
            "score": 58.8
          }
        ],
        "editorialScores": {
          "ergonomics": 63,
          "maintenance": 74,
          "payments": 40,
          "reliability": 65,
          "schema": 60,
          "security": 48,
          "transparency": 60
        },
        "provenanceScore": 76
      },
      "connect": {
        "install": "yarn add expo-server-sdk",
        "http": "curl -H \"Content-Type: application/json\" -X POST \"https://exp.host/--/api/v2/push/send\" -d '{\n  \"to\": \"ExponentPushToken[xxxxxxxxxxxxxxxxxxxxxx]\",\n  \"title\":\"hello\",\n  \"body\": \"world\"\n}'"
      },
      "letme": {
        "capability": "https://letme.dev/notify.push",
        "tool": "https://letme.dev/expo-push-notifications"
      },
      "area": "everyday",
      "provenance": {
        "legalEntity": "650 Industries, Inc.",
        "domain": "expo.dev",
        "domainRegistered": "2019-02-22",
        "endpointOnVendorDomain": false,
        "terms": "https://expo.dev/terms",
        "privacy": "https://expo.dev/privacy",
        "statusPage": "https://status.expo.dev",
        "changelog": "https://github.com/expo/expo-server-sdk-node/blob/main/CHANGELOG.md",
        "securityTxt": "valid",
        "checked": "2026-10-09",
        "notes": [
          "The terms (last updated 29 May 2025, effective 30 June 2025) are a contract with 650 Industries, Inc. and cover any product or service Expo makes available. They list EAS Build, Update, Submit, Hosting and Workflows by name and do not name the push service.",
          "The push API answers at exp.host, a second domain. Expo's docs and its Node SDK source name that host.",
          "expo.dev/.well-known/security.txt gives vulnerability-disclosures@expo.dev and a Canonical line and has no Expires field, which RFC 9116 requires.",
          "The privacy policy (last updated 21 October 2025) says Expo may collect end users' push tokens when the push service is used.",
          "expo.dev/robots.txt disallows `/expo-subscription-agreement`, so that agreement was not read.",
          "The registry's RDAP record for expo.dev gives a registration date of 2019-02-22. The changelog link is the Node SDK's, because no changelog for the push API itself was found."
        ],
        "score": 76
      },
      "pageJsonUrl": "https://www.anchorterminal.com/tools/expo-push-notifications.json",
      "live": {
        "slug": "expo-push-notifications",
        "probe": {
          "target": "https://exp.host/--/api/v2/push/send",
          "method": "get",
          "lastAt": "2026-10-10T02:07:08.51757843Z",
          "lastOk": true,
          "lastStatus": 405,
          "lastMs": 120,
          "authRequired": false,
          "uptime24h": 100,
          "uptime30d": 100,
          "p50ms24h": 128,
          "p95ms24h": 197,
          "samples24h": 107,
          "samples30d": 107,
          "days": [
            {
              "date": "2026-10-09",
              "probes": 85,
              "ok": 85
            },
            {
              "date": "2026-10-10",
              "probes": 22,
              "ok": 22
            }
          ]
        },
        "vendorStatus": {
          "page": "https://status.expo.dev",
          "indicator": "none",
          "summary": "All Systems Operational",
          "checkedAt": "2026-10-10T02:05:59.612219912Z"
        },
        "versions": [
          {
            "registry": "github",
            "name": "expo/expo-server-sdk-node",
            "version": "v7.2.0",
            "released": "2026-08-24",
            "seenAt": "2026-10-09T16:52:32.455380467Z"
          },
          {
            "registry": "npm",
            "name": "expo-server-sdk",
            "version": "7.2.0",
            "seenAt": "2026-10-09T16:52:31.59453516Z"
          }
        ],
        "githubStars": 1037,
        "npmWeekly": 1348515,
        "pages": [
          {
            "url": "https://raw.githubusercontent.com/expo/expo-server-sdk-node/main/CHANGELOG.md",
            "kind": "changelog",
            "status": 200,
            "checkedAt": "2026-10-09T18:45:09.224081599Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "851125e2dd50"
          },
          {
            "url": "https://expo.dev/privacy",
            "kind": "privacy",
            "status": 200,
            "checkedAt": "2026-10-09T18:39:14.02772659Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "42bd6fab5bc9"
          },
          {
            "url": "https://expo.dev/terms",
            "kind": "terms",
            "status": 200,
            "checkedAt": "2026-10-09T18:39:16.223165435Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "d061e1a55580"
          }
        ],
        "updatedAt": "2026-10-10T02:07:08.51757843Z"
      }
    },
    "answer": "Firebase Cloud Messaging scores 69.8 (B) on agent readiness against Expo Push Notifications's 58.8 (C), and leads in 6 of 7 scored categories.",
    "b": {
      "slug": "firebase-cloud-messaging",
      "name": "Firebase Cloud Messaging",
      "vendor": "Google",
      "vendorUrl": "https://firebase.google.com/products/cloud-messaging",
      "kind": "http-api",
      "category": "notifications",
      "summary": "Google's push messaging service for Android, Apple and web apps. A server sends notification or data messages to devices, topics or conditions through the HTTP v1 API or the Firebase Admin SDKs.",
      "url": "https://www.anchorterminal.com/tools/firebase-cloud-messaging",
      "markdownUrl": "https://www.anchorterminal.com/tools/firebase-cloud-messaging.md",
      "slimMarkdownUrl": "https://www.anchorterminal.com/tools/firebase-cloud-messaging.min.md",
      "jsonUrl": "https://www.anchorterminal.com/api/v1/tools/firebase-cloud-messaging.json",
      "repo": "https://github.com/firebase/firebase-admin-node",
      "license": "Proprietary service under the Google APIs Terms of Service. The Firebase Admin SDKs are Apache-2.0",
      "transports": [
        "http"
      ],
      "remoteUrl": "https://fcm.googleapis.com",
      "packages": [
        {
          "registry": "npm",
          "name": "firebase-admin"
        },
        {
          "registry": "pypi",
          "name": "firebase-admin"
        }
      ],
      "auth": "oauth",
      "authNotes": "OAuth 2.0 bearer token minted from a service account key or Application Default Credentials, with the scope `https://www.googleapis.com/auth/firebase.messaging`. Sending needs the IAM permission `cloudmessaging.messages.create` on the project. Access is self-serve. A person creates the Firebase project and the service account in the console, with no review or sales step.",
      "pricing": "free",
      "pricingNotes": "No charge. The pricing page lists Cloud Messaging as no-cost on the Spark and Blaze plans, and Spark needs no billing account or card, so an agent's owner can start without a contract. The optional BigQuery export of delivery data is billed by BigQuery (https://firebase.google.com/pricing, checked 2026-10-08).",
      "priceSummary": "Free",
      "where": "hosted",
      "x402": {
        "level": "no",
        "evidence": "No x402, MPP or L402 in the FCM docs, the Discovery document or the pricing page (checked 2026-10-08).",
        "endpoints": []
      },
      "toolCount": null,
      "popularity": {
        "githubStars": null,
        "npmWeekly": 11536195,
        "pypiWeekly": 3790113,
        "asOf": "2026-10-08"
      },
      "docsUrl": "https://firebase.google.com/docs/cloud-messaging",
      "llmsTxt": "https://firebase.google.com/docs/llms.txt",
      "openapi": "https://fcm.googleapis.com/$discovery/rest?version=v1",
      "capabilities": [
        "notify.push"
      ],
      "tags": [
        "hosted",
        "free",
        "push",
        "oauth",
        "llms-txt",
        "typescript",
        "python",
        "java",
        "go",
        "dotnet",
        "mcp",
        "status-page",
        "soc2"
      ],
      "lastRelease": "2026-09-24",
      "graded": true,
      "anchor": {
        "graded": true,
        "score": 69.8,
        "grade": "B",
        "agentReady": false,
        "rank": 170,
        "ranked": true,
        "rankOf": 950,
        "categoryRank": 4,
        "methodology": "0.4",
        "run": "2026-10-01",
        "scores": {
          "ergonomics": 70,
          "maintenance": 83,
          "payments": 40,
          "reliability": 66,
          "schema": 86,
          "security": 68,
          "transparency": 81
        },
        "pending": [
          "performance",
          "tasks"
        ],
        "assessment": {
          "confidence": "medium",
          "date": "2026-10-08"
        },
        "negative": 0,
        "verdict": "Sending is free at any volume, with a published quota of 600,000 messages a minute per project and documented 429 handling. FCM is push transport only. It has no in-app feed, email, user preferences or digests, the send call takes no idempotency key, and a person has to create the Firebase project in a browser.",
        "bestFor": "The push transport under an app that already holds device registrations, at no charge.",
        "strengths": [
          "No charge for sending on either Firebase plan, and no billing account needed (https://firebase.google.com/pricing)",
          "Default quota of 600,000 messages a minute per project, with 429 responses that carry `retry-after` and written backoff guidance",
          "Short-lived OAuth 2.0 tokens with a `firebase.messaging` scope, and IAM permissions per action such as `cloudmessaging.messages.create`",
          "Public Discovery document (revision 20261006), a docs `llms.txt` and a Markdown twin of every docs page",
          "Dated deprecation notice in September 2026 that gives 12 months before the Instance ID server APIs and device groups stop on 29 September 2027"
        ],
        "weaknesses": [
          "Push transport only. No in-app feed, email, SMS, user preferences, digests or templates",
          "No idempotency key on `messages:send`, so a retried request can reach the device twice",
          "One HTTP request per message. Only the Admin SDKs group up to 500 sends in a call",
          "FCM is absent from Google Cloud's list of services with audit logs, and per-message delivery data needs a BigQuery export",
          "One incident on 1 September 2026 lowered availability in North America for 3 hours 51 minutes, and no SLA names FCM"
        ],
        "agentNotes": [
          "Mint an access token from a service account with the scope `https://www.googleapis.com/auth/firebase.messaging`, then POST to `https://fcm.googleapis.com/v1/projects/\u003cproject-id\u003e/messages:send`",
          "Set `validate_only` to true to test a message or a registration without sending it",
          "On 429 wait for the `retry-after` header, or 60 seconds if it is absent. Retry 500 and 503 with exponential backoff and jitter, and never retry 400, 401, 403 or 404",
          "Drop a registration when the error is `UNREGISTERED` (404). Keep your own record of sends, because a retry after a timeout can produce a duplicate",
          "Target `fid` in new code. The `token` field is marked deprecated in the API, and device groups stop working after 29 September 2027"
        ],
        "metrics": {
          "kind": "remote",
          "measured": false
        },
        "reviewCount": 0,
        "avgRating": 0,
        "history": [
          {
            "basis": "public evidence",
            "confidence": "medium",
            "grade": "B",
            "methodology": "0.4",
            "pending": [
              "performance",
              "tasks"
            ],
            "run": "2026-10-01",
            "runLabel": "October 2026 research run",
            "score": 69.8
          }
        ],
        "editorialScores": {
          "ergonomics": 70,
          "maintenance": 83,
          "payments": 40,
          "reliability": 66,
          "schema": 86,
          "security": 68,
          "transparency": 68
        },
        "provenanceScore": 94
      },
      "connect": {
        "install": "npm install firebase-admin   # or: pip install firebase-admin",
        "http": "curl -X POST \"https://fcm.googleapis.com/v1/projects/$FIREBASE_PROJECT_ID/messages:send\" \\\n  -H \"Authorization: Bearer $ACCESS_TOKEN\" -H \"Content-Type: application/json\" \\\n  -d '{\"message\":{\"topic\":\"news\",\"notification\":{\"title\":\"Build finished\",\"body\":\"All tests passed\"}}}'",
        "claudeCode": "claude mcp add firebase npx -- -y firebase-tools@latest mcp"
      },
      "letme": {
        "capability": "https://letme.dev/notify.push",
        "tool": "https://letme.dev/firebase-cloud-messaging"
      },
      "sameCompany": [
        "gemini-api",
        "gemini-embedding",
        "vertex-ai-tuning",
        "google-model-armor",
        "google-imagen",
        "google-veo",
        "google-lyria",
        "google-speech-to-text",
        "gemini-live",
        "google-adk",
        "google-secret-manager",
        "google-cloud-document-ai",
        "google-weather-api",
        "chrome-devtools-mcp",
        "google-maps-platform",
        "google-cloud-translation",
        "google-calendar-api",
        "google-drive-api",
        "gemini-cli",
        "google-search-console",
        "google-ads-api",
        "google-forms",
        "google-sheets-api",
        "gmail-api"
      ],
      "area": "everyday",
      "provenance": {
        "legalEntity": "Google LLC",
        "domain": "google.com",
        "domainRegistered": "1997-09-15",
        "domainNote": "The endpoint is on googleapis.com, Google's API domain. The docs are on firebase.google.com.",
        "endpointOnVendorDomain": true,
        "terms": "https://developers.google.com/terms",
        "privacy": "https://policies.google.com/privacy",
        "statusPage": "https://status.firebase.google.com",
        "changelog": "https://firebase.google.com/support/releases",
        "securityTxt": "valid",
        "checked": "2026-10-08",
        "notes": [
          "firebase.google.com/terms, last modified 24 September 2026, places Cloud Messaging under the Google APIs Terms of Service and the Firebase Data Processing and Security Terms.",
          "The Google APIs Terms of Service were last modified on 9 November 2021, name Google LLC of Mountain View, California, and choose California law.",
          "Google's privacy policy is effective 1 October 2026. Firebase's own privacy and security page, last modified 15 September 2026, gives the per-service data and retention table.",
          "www.google.com/.well-known/security.txt expires on 2030-04-01. firebase.google.com/.well-known/security.txt returns 404.",
          "The registration date of google.com is taken from our earlier Google listings and was not looked up again today."
        ],
        "score": 94
      },
      "pageJsonUrl": "https://www.anchorterminal.com/tools/firebase-cloud-messaging.json",
      "live": {
        "slug": "firebase-cloud-messaging",
        "probe": {
          "target": "https://fcm.googleapis.com",
          "method": "get",
          "lastAt": "2026-10-10T02:07:09.050529644Z",
          "lastOk": true,
          "lastStatus": 404,
          "lastMs": 41,
          "authRequired": false,
          "uptime24h": 100,
          "uptime30d": 100,
          "p50ms24h": 42,
          "p95ms24h": 136,
          "samples24h": 191,
          "samples30d": 191,
          "days": [
            {
              "date": "2026-10-09",
              "probes": 169,
              "ok": 169
            },
            {
              "date": "2026-10-10",
              "probes": 22,
              "ok": 22
            }
          ]
        },
        "vendorStatus": {
          "page": "https://status.firebase.google.com",
          "indicator": "unknown",
          "summary": "no machine-readable status found",
          "checkedAt": "2026-10-10T00:50:34.166259109Z"
        },
        "versions": [
          {
            "registry": "github",
            "name": "firebase/firebase-admin-node",
            "version": "v14.5.0",
            "released": "2026-09-23",
            "seenAt": "2026-10-09T16:53:18.587855434Z"
          },
          {
            "registry": "npm",
            "name": "firebase-admin",
            "version": "14.5.0",
            "seenAt": "2026-10-09T16:53:17.601587804Z"
          },
          {
            "registry": "pypi",
            "name": "firebase-admin",
            "version": "7.7.0",
            "released": "2026-09-23",
            "seenAt": "2026-10-09T16:53:18.42206492Z"
          }
        ],
        "githubStars": 1750,
        "npmWeekly": 9821375,
        "pypiWeekly": 3780074,
        "securityTxt": {
          "url": "https://google.com/.well-known/security.txt",
          "state": "valid",
          "expires": "2030-04-01T00:00:00z",
          "checkedAt": "2026-10-09T15:39:28.443612679Z"
        },
        "llmsTxt": {
          "url": "https://firebase.google.com/docs/llms.txt",
          "ok": true,
          "status": 200,
          "checkedAt": "2026-10-09T14:02:03.112222164Z"
        },
        "pages": [
          {
            "url": "https://firebase.google.com/support/releases",
            "kind": "changelog",
            "status": 200,
            "checkedAt": "2026-10-09T18:39:28.508823146Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "55a63ea6d5b0"
          },
          {
            "url": "https://firebase.google.com/pricing",
            "kind": "pricing",
            "status": 200,
            "checkedAt": "2026-10-09T18:39:25.617080484Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "d3dc20920b5b"
          },
          {
            "url": "https://developers.google.com/terms",
            "kind": "terms",
            "status": 200,
            "checkedAt": "2026-10-09T18:35:57.610846795Z",
            "changedAt": "0001-01-01T00:00:00Z",
            "fingerprint": "2eb11136bf24"
          }
        ],
        "updatedAt": "2026-10-10T02:07:09.050529644Z"
      }
    },
    "facts": [
      {
        "a": "HTTP API",
        "b": "HTTP API",
        "name": "Kind"
      },
      {
        "a": "Expo",
        "b": "Google",
        "name": "Vendor"
      },
      {
        "a": "https://exp.host/--/api/v2/push/send",
        "b": "https://fcm.googleapis.com",
        "name": "Hosted endpoint"
      },
      {
        "a": "HTTP",
        "b": "HTTP",
        "name": "Transports"
      },
      {
        "a": "OAuth or key",
        "b": "OAuth",
        "name": "Auth"
      },
      {
        "a": "Free",
        "b": "Free",
        "name": "Pricing"
      },
      {
        "a": "no",
        "b": "no",
        "name": "x402"
      },
      {
        "a": "Proprietary service under Expo's terms of service. The Node.js server SDK is MIT",
        "b": "Proprietary service under the Google APIs Terms of Service. The Firebase Admin SDKs are Apache-2.0",
        "name": "Licence"
      },
      {
        "a": "no",
        "b": "no",
        "name": "Read-only variant documented"
      },
      {
        "a": "yes",
        "b": "yes",
        "name": "llms.txt"
      },
      {
        "a": "2026-08-24",
        "b": "2026-09-24",
        "name": "Last release"
      },
      {
        "a": "2025-05-29",
        "b": "2021-11-09",
        "name": "Terms last updated"
      },
      {
        "a": "2025-10-21",
        "b": "2026-10-01",
        "name": "Privacy policy last updated"
      },
      {
        "a": "not found in the text",
        "b": "yes",
        "name": "Customer content may train models"
      },
      {
        "a": "yes",
        "b": "yes",
        "name": "Terms restrict automated access"
      },
      {
        "a": "not found in the text",
        "b": "not found in the text",
        "name": "Terms restrict benchmarking"
      },
      {
        "a": "yes",
        "b": "not found in the text",
        "name": "Terms or service can change without notice"
      },
      {
        "a": "yes",
        "b": "not found in the text",
        "name": "Arbitration or class-action waiver"
      },
      {
        "a": "1k stars, 1.3M npm/wk",
        "b": "11.5M npm/wk, 3.8M PyPI/wk",
        "name": "Popularity"
      }
    ],
    "faq": [
      {
        "answer": "Firebase Cloud Messaging scores 69.8 (B) on agent readiness against Expo Push Notifications's 58.8 (C), and leads in 6 of 7 scored categories.",
        "question": "Which is better for AI agents, Expo Push Notifications or Firebase Cloud Messaging?"
      },
      {
        "answer": "Expo Push Notifications takes an API key or an OAuth sign-in. Firebase Cloud Messaging uses an OAuth sign-in.",
        "question": "Do Expo Push Notifications and Firebase Cloud Messaging need an API key?"
      },
      {
        "answer": "Yes. Expo Push Notifications has a hosted endpoint at https://exp.host/--/api/v2/push/send and Firebase Cloud Messaging at https://fcm.googleapis.com.",
        "question": "Can an agent call Expo Push Notifications and Firebase Cloud Messaging without installing anything?"
      }
    ],
    "goodFor": [
      {
        "aheadOn": null,
        "also": null,
        "goodFor": "An agent that must push to an app already built with Expo, at no cost and with one call for both platforms.",
        "slug": "expo-push-notifications",
        "watchFor": "The send API needs no authentication by default, so anyone holding a push token can send to that device until the owner enables access tokens"
      },
      {
        "aheadOn": [
          "Schema \u0026 documentation, 86 against 60",
          "Agent ergonomics, 70 against 63",
          "Security \u0026 auth, 68 against 48",
          "Maintenance \u0026 community, 83 against 74",
          "Transparency \u0026 trust, 81 against 68"
        ],
        "also": null,
        "goodFor": "The push transport under an app that already holds device registrations, at no charge.",
        "slug": "firebase-cloud-messaging",
        "watchFor": "Push transport only. No in-app feed, email, SMS, user preferences, digests or templates"
      }
    ],
    "job": {
      "capability": "notify.push",
      "name": "Push notifications"
    },
    "others": [
      {
        "json": "https://www.anchorterminal.com/compare/amazon-sns-vs-expo-push-notifications.json",
        "title": "Amazon SNS vs Expo Push Notifications",
        "url": "https://www.anchorterminal.com/compare/amazon-sns-vs-expo-push-notifications"
      },
      {
        "json": "https://www.anchorterminal.com/compare/amazon-sns-vs-firebase-cloud-messaging.json",
        "title": "Amazon SNS vs Firebase Cloud Messaging",
        "url": "https://www.anchorterminal.com/compare/amazon-sns-vs-firebase-cloud-messaging"
      },
      {
        "json": "https://www.anchorterminal.com/compare/courier-vs-expo-push-notifications.json",
        "title": "Courier vs Expo Push Notifications",
        "url": "https://www.anchorterminal.com/compare/courier-vs-expo-push-notifications"
      },
      {
        "json": "https://www.anchorterminal.com/compare/courier-vs-firebase-cloud-messaging.json",
        "title": "Courier vs Firebase Cloud Messaging",
        "url": "https://www.anchorterminal.com/compare/courier-vs-firebase-cloud-messaging"
      },
      {
        "json": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-knock.json",
        "title": "Expo Push Notifications vs Knock",
        "url": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-knock"
      },
      {
        "json": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-magicbell.json",
        "title": "Expo Push Notifications vs MagicBell",
        "url": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-magicbell"
      },
      {
        "json": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-novu.json",
        "title": "Expo Push Notifications vs Novu",
        "url": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-novu"
      },
      {
        "json": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-ntfy.json",
        "title": "Expo Push Notifications vs ntfy",
        "url": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-ntfy"
      },
      {
        "json": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-onesignal.json",
        "title": "Expo Push Notifications vs OneSignal",
        "url": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-onesignal"
      },
      {
        "json": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-pingram.json",
        "title": "Expo Push Notifications vs Pingram",
        "url": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-pingram"
      },
      {
        "json": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-pushover.json",
        "title": "Expo Push Notifications vs Pushover",
        "url": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-pushover"
      },
      {
        "json": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-suprsend.json",
        "title": "Expo Push Notifications vs SuprSend",
        "url": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-suprsend"
      },
      {
        "json": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-knock.json",
        "title": "Firebase Cloud Messaging vs Knock",
        "url": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-knock"
      },
      {
        "json": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-magicbell.json",
        "title": "Firebase Cloud Messaging vs MagicBell",
        "url": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-magicbell"
      },
      {
        "json": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-novu.json",
        "title": "Firebase Cloud Messaging vs Novu",
        "url": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-novu"
      },
      {
        "json": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-ntfy.json",
        "title": "Firebase Cloud Messaging vs ntfy",
        "url": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-ntfy"
      },
      {
        "json": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-onesignal.json",
        "title": "Firebase Cloud Messaging vs OneSignal",
        "url": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-onesignal"
      },
      {
        "json": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-pingram.json",
        "title": "Firebase Cloud Messaging vs Pingram",
        "url": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-pingram"
      },
      {
        "json": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-pushover.json",
        "title": "Firebase Cloud Messaging vs Pushover",
        "url": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-pushover"
      },
      {
        "json": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-suprsend.json",
        "title": "Firebase Cloud Messaging vs SuprSend",
        "url": "https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-suprsend"
      }
    ],
    "scores": [
      {
        "by": 1,
        "edge": "firebase-cloud-messaging",
        "expo-push-notifications": 65,
        "firebase-cloud-messaging": 66,
        "key": "reliability",
        "name": "Reliability",
        "weight": 16
      },
      {
        "key": "performance",
        "name": "Performance",
        "pending": true,
        "weight": 10
      },
      {
        "by": 26,
        "edge": "firebase-cloud-messaging",
        "expo-push-notifications": 60,
        "firebase-cloud-messaging": 86,
        "key": "schema",
        "name": "Schema \u0026 documentation",
        "weight": 13
      },
      {
        "by": 7,
        "edge": "firebase-cloud-messaging",
        "expo-push-notifications": 63,
        "firebase-cloud-messaging": 70,
        "key": "ergonomics",
        "name": "Agent ergonomics",
        "weight": 13
      },
      {
        "by": 20,
        "edge": "firebase-cloud-messaging",
        "expo-push-notifications": 48,
        "firebase-cloud-messaging": 68,
        "key": "security",
        "name": "Security \u0026 auth",
        "weight": 14
      },
      {
        "by": 0,
        "edge": "",
        "expo-push-notifications": 40,
        "firebase-cloud-messaging": 40,
        "key": "payments",
        "name": "Payments \u0026 pricing",
        "weight": 10
      },
      {
        "key": "tasks",
        "name": "Task success",
        "pending": true,
        "weight": 10
      },
      {
        "by": 9,
        "edge": "firebase-cloud-messaging",
        "expo-push-notifications": 74,
        "firebase-cloud-messaging": 83,
        "key": "maintenance",
        "name": "Maintenance \u0026 community",
        "weight": 7
      },
      {
        "by": 13,
        "edge": "firebase-cloud-messaging",
        "expo-push-notifications": 68,
        "firebase-cloud-messaging": 81,
        "key": "transparency",
        "name": "Transparency \u0026 trust",
        "weight": 7
      }
    ],
    "summary": "Firebase Cloud Messaging scores 69.8 (B) on agent readiness against Expo Push Notifications's 58.8 (C), and leads in 6 of 7 scored categories. Both do push notifications.",
    "verdicts": {
      "expo-push-notifications": "A free push relay with a small, well documented HTTP API, published limits of 600 notifications a second and written error codes. Sending needs no credential unless the owner turns on access tokens, there is no idempotency key or SLA, and the status page records three iOS push incidents since 4 August 2026.",
      "firebase-cloud-messaging": "Sending is free at any volume, with a published quota of 600,000 messages a minute per project and documented 429 handling. FCM is push transport only. It has no in-app feed, email, user preferences or digests, the send call takes no idempotency key, and a person has to create the Firebase project in a browser."
    }
  },
  "kind": "anchor.page",
  "links": {
    "api": "https://www.anchorterminal.com/api/v1/index.json",
    "html": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-firebase-cloud-messaging",
    "json": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-firebase-cloud-messaging.json",
    "llms": "https://www.anchorterminal.com/llms.txt",
    "markdown": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-firebase-cloud-messaging.md",
    "slim": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-firebase-cloud-messaging.min.md"
  },
  "markdown": "Firebase Cloud Messaging scores 69.8 (B) on agent readiness against Expo Push Notifications's 58.8 (C), and leads in 6 of 7 scored categories. Both do push notifications.\n\n- Expo Push Notifications: grade C, 58.8/100, rank #571 of 950. Markdown https://www.anchorterminal.com/tools/expo-push-notifications.md · JSON https://www.anchorterminal.com/api/v1/tools/expo-push-notifications.json\n- Firebase Cloud Messaging: grade B, 69.8/100, rank #170 of 950. Markdown https://www.anchorterminal.com/tools/firebase-cloud-messaging.md · JSON https://www.anchorterminal.com/api/v1/tools/firebase-cloud-messaging.json\n- Best notification APIs for AI agents: https://www.anchorterminal.com/best/notifications/index.md\n- All 66 notifications comparisons: https://www.anchorterminal.com/compare/notifications/index.md\n\n## Which one, for what\n\n### Expo Push Notifications (C)\n\nGood for: An agent that must push to an app already built with Expo, at no cost and with one call for both platforms.\n\nWatch for: The send API needs no authentication by default, so anyone holding a push token can send to that device until the owner enables access tokens\n\n### Firebase Cloud Messaging (B)\n\nGood for: The push transport under an app that already holds device registrations, at no charge.\n\nAhead on:\n- Schema \u0026 documentation, 86 against 60\n- Agent ergonomics, 70 against 63\n- Security \u0026 auth, 68 against 48\n- Maintenance \u0026 community, 83 against 74\n- Transparency \u0026 trust, 81 against 68\n\nWatch for: Push transport only. No in-app feed, email, SMS, user preferences, digests or templates\n\n\n## Score by category\n\n| Category | Weight | Expo Push Notifications | Firebase Cloud Messaging | Edge |\n| --- | --- | --- | --- | --- |\n| Reliability | 16% (20 this run) | 65 | 66 | Firebase Cloud Messaging +1 |\n| Performance | 10%, pending | pending | pending | not scored in this run |\n| Schema \u0026 documentation | 13% (16.2 this run) | 60 | 86 | Firebase Cloud Messaging +26 |\n| Agent ergonomics | 13% (16.2 this run) | 63 | 70 | Firebase Cloud Messaging +7 |\n| Security \u0026 auth | 14% (17.5 this run) | 48 | 68 | Firebase Cloud Messaging +20 |\n| Payments \u0026 pricing | 10% (12.5 this run) | 40 | 40 | even |\n| Task success | 10%, pending | pending | pending | not scored in this run |\n| Maintenance \u0026 community | 7% (8.8 this run) | 74 | 83 | Firebase Cloud Messaging +9 |\n| Transparency \u0026 trust | 7% (8.8 this run) | 68 | 81 | Firebase Cloud Messaging +13 |\n| Negative events | ≤15 | 0 | 0 | |\n| **Total** | | **58.8 · C** | **69.8 · B** | |\n\n## Facts side by side\n\n| Fact | Expo Push Notifications | Firebase Cloud Messaging |\n| --- | --- | --- |\n| Kind | HTTP API | HTTP API |\n| Vendor | Expo | Google |\n| Hosted endpoint | `https://exp.host/--/api/v2/push/send` | `https://fcm.googleapis.com` |\n| Transports | HTTP | HTTP |\n| Auth | OAuth or key | OAuth |\n| Pricing | Free | Free |\n| x402 | no | no |\n| Licence | Proprietary service under Expo's terms of service. The Node.js server SDK is MIT | Proprietary service under the Google APIs Terms of Service. The Firebase Admin SDKs are Apache-2.0 |\n| Read-only variant documented | no | no |\n| llms.txt | yes | yes |\n| Last release | 2026-08-24 | 2026-09-24 |\n| Terms last updated | 2025-05-29 | 2021-11-09 |\n| Privacy policy last updated | 2025-10-21 | 2026-10-01 |\n| Customer content may train models | not found in the text | yes |\n| Terms restrict automated access | yes | yes |\n| Terms restrict benchmarking | not found in the text | not found in the text |\n| Terms or service can change without notice | yes | not found in the text |\n| Arbitration or class-action waiver | yes | not found in the text |\n| Popularity | 1k stars, 1.3M npm/wk | 11.5M npm/wk, 3.8M PyPI/wk |\n\n## Verdicts\n\n**Expo Push Notifications.** A free push relay with a small, well documented HTTP API, published limits of 600 notifications a second and written error codes. Sending needs no credential unless the owner turns on access tokens, there is no idempotency key or SLA, and the status page records three iOS push incidents since 4 August 2026.\n\n**Firebase Cloud Messaging.** Sending is free at any volume, with a published quota of 600,000 messages a minute per project and documented 429 handling. FCM is push transport only. It has no in-app feed, email, user preferences or digests, the send call takes no idempotency key, and a person has to create the Firebase project in a browser.\n\n## Before you call either\n\n### Expo Push Notifications\n\n1. Send an array of up to 100 messages per request, all for one project, and stay under 600 notifications a second\n2. Keep each ticket `id` and POST them to `/--/api/v2/push/getReceipts` about 15 minutes later. Receipts are cleared after 24 hours\n3. Stop sending to a token when a ticket or receipt returns `DeviceNotRegistered`\n4. If the project has enhanced push security on, send `Authorization: Bearer \u003caccess token\u003e` or the call fails with `UNAUTHORIZED`\n5. Retry 429 and 5xx with exponential backoff, and expect an occasional duplicate because there is no idempotency key\n\n### Firebase Cloud Messaging\n\n1. Mint an access token from a service account with the scope `https://www.googleapis.com/auth/firebase.messaging`, then POST to `https://fcm.googleapis.com/v1/projects/\u003cproject-id\u003e/messages:send`\n2. Set `validate_only` to true to test a message or a registration without sending it\n3. On 429 wait for the `retry-after` header, or 60 seconds if it is absent. Retry 500 and 503 with exponential backoff and jitter, and never retry 400, 401, 403 or 404\n4. Drop a registration when the error is `UNREGISTERED` (404). Keep your own record of sends, because a retry after a timeout can produce a duplicate\n5. Target `fid` in new code. The `token` field is marked deprecated in the API, and device groups stop working after 29 September 2027\n\n## Questions\n\n### Which is better for AI agents, Expo Push Notifications or Firebase Cloud Messaging?\n\nFirebase Cloud Messaging scores 69.8 (B) on agent readiness against Expo Push Notifications's 58.8 (C), and leads in 6 of 7 scored categories.\n\n### Do Expo Push Notifications and Firebase Cloud Messaging need an API key?\n\nExpo Push Notifications takes an API key or an OAuth sign-in. Firebase Cloud Messaging uses an OAuth sign-in.\n\n### Can an agent call Expo Push Notifications and Firebase Cloud Messaging without installing anything?\n\nYes. Expo Push Notifications has a hosted endpoint at https://exp.host/--/api/v2/push/send and Firebase Cloud Messaging at https://fcm.googleapis.com.\n\n\n## For agents\n\n- This comparison as JSON: https://www.anchorterminal.com/compare/expo-push-notifications-vs-firebase-cloud-messaging.json, and with the fewest tokens: https://www.anchorterminal.com/compare/expo-push-notifications-vs-firebase-cloud-messaging.min.md\n- Over MCP at https://www.anchorterminal.com/mcp (no key): `compare_tools {\"a\": \"expo-push-notifications\", \"b\": \"firebase-cloud-messaging\"}`. From a terminal: `anchor compare expo-push-notifications firebase-cloud-messaging`\n- Each listing in full: https://www.anchorterminal.com/api/v1/tools/expo-push-notifications.json and https://www.anchorterminal.com/api/v1/tools/firebase-cloud-messaging.json\n\n## Other comparisons with Expo Push Notifications or Firebase Cloud Messaging\n\n- [Amazon SNS vs Expo Push Notifications](https://www.anchorterminal.com/compare/amazon-sns-vs-expo-push-notifications.md)\n- [Amazon SNS vs Firebase Cloud Messaging](https://www.anchorterminal.com/compare/amazon-sns-vs-firebase-cloud-messaging.md)\n- [Courier vs Expo Push Notifications](https://www.anchorterminal.com/compare/courier-vs-expo-push-notifications.md)\n- [Courier vs Firebase Cloud Messaging](https://www.anchorterminal.com/compare/courier-vs-firebase-cloud-messaging.md)\n- [Expo Push Notifications vs Knock](https://www.anchorterminal.com/compare/expo-push-notifications-vs-knock.md)\n- [Expo Push Notifications vs MagicBell](https://www.anchorterminal.com/compare/expo-push-notifications-vs-magicbell.md)\n- [Expo Push Notifications vs Novu](https://www.anchorterminal.com/compare/expo-push-notifications-vs-novu.md)\n- [Expo Push Notifications vs ntfy](https://www.anchorterminal.com/compare/expo-push-notifications-vs-ntfy.md)\n- [Expo Push Notifications vs OneSignal](https://www.anchorterminal.com/compare/expo-push-notifications-vs-onesignal.md)\n- [Expo Push Notifications vs Pingram](https://www.anchorterminal.com/compare/expo-push-notifications-vs-pingram.md)\n- [Expo Push Notifications vs Pushover](https://www.anchorterminal.com/compare/expo-push-notifications-vs-pushover.md)\n- [Expo Push Notifications vs SuprSend](https://www.anchorterminal.com/compare/expo-push-notifications-vs-suprsend.md)\n- [Firebase Cloud Messaging vs Knock](https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-knock.md)\n- [Firebase Cloud Messaging vs MagicBell](https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-magicbell.md)\n- [Firebase Cloud Messaging vs Novu](https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-novu.md)\n- [Firebase Cloud Messaging vs ntfy](https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-ntfy.md)\n- [Firebase Cloud Messaging vs OneSignal](https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-onesignal.md)\n- [Firebase Cloud Messaging vs Pingram](https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-pingram.md)\n- [Firebase Cloud Messaging vs Pushover](https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-pushover.md)\n- [Firebase Cloud Messaging vs SuprSend](https://www.anchorterminal.com/compare/firebase-cloud-messaging-vs-suprsend.md)\n",
  "meta": {
    "attribution": "Anchor Terminal (https://www.anchorterminal.com)",
    "docs": "https://www.anchorterminal.com/docs/",
    "generatedAt": "2026-10-10",
    "license": "CC-BY-4.0",
    "method": "https://www.anchorterminal.com/benchmark/",
    "methodology": "0.4",
    "openapi": "https://www.anchorterminal.com/openapi.json",
    "preview": false,
    "run": "2026-10-01",
    "runLabel": "October 2026 research run"
  },
  "page": {
    "breadcrumbs": [
      {
        "name": "Home",
        "url": "https://www.anchorterminal.com/"
      },
      {
        "name": "Compare",
        "url": "https://www.anchorterminal.com/compare/"
      },
      {
        "name": "Expo Push Notifications vs Firebase Cloud Messaging",
        "url": ""
      }
    ],
    "description": "Firebase Cloud Messaging scores 69.8 (B) to Expo Push Notifications's 58.8 (C) for push notifications. Prices, MCP, x402, uptime and agent notes side by side.",
    "facts": [
      "Expo Push Notifications C 58.8",
      "Firebase Cloud Messaging B 69.8",
      "scores"
    ],
    "h1": "Expo Push Notifications vs Firebase Cloud Messaging",
    "image": "https://www.anchorterminal.com/assets/og/compare-expo-push-notifications-vs-firebase-cloud-messaging.png",
    "path": "/compare/expo-push-notifications-vs-firebase-cloud-messaging",
    "published": "2026-10-01",
    "section": "tools",
    "title": "Expo Push Notifications vs Firebase Cloud Messaging (2026)",
    "toc": null,
    "updated": "2026-10-09",
    "url": "https://www.anchorterminal.com/compare/expo-push-notifications-vs-firebase-cloud-messaging"
  },
  "tokens": {
    "markdown": 2600,
    "slim": 680
  },
  "version": 1
}
