{
  "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"
  },
  "tool": {
    "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"
      ],
      "breakdown": [
        {
          "key": "reliability",
          "name": "Reliability",
          "weight": 16,
          "effectiveWeight": 20,
          "score": 65,
          "points": 13,
          "reason": "Hosted reading. status.expo.dev is a Statuspage site with a Push Notifications Broker component (20). The incident feed reaches back only to 4 August 2026, so 11 July to 3 August went unread. It lists three push incidents, an iOS push partial outage on 4 August lasting 83 minutes, delayed iOS push for an hour on 5 September and an iOS queue backlog on 8 September lasting 4 hours 41 minutes, plus wider API and website incidents on 1 September and 5 October. Read as one major incident (10). Limits are published with numbers, 600 notifications a second per project, 100 messages a request and 1,000 receipt IDs a request (15). The docs tell callers to retry 429 and 5xx with exponential backoff and the Node SDK does so twice on 429. No Retry-After header is documented and there is no idempotency key, while Expo says a notification may be handed on more than once (10 of 15). The docs state the push service has no SLA (0). The API is generally available (10)."
        },
        {
          "key": "performance",
          "name": "Performance",
          "weight": 10,
          "effectiveWeight": 0,
          "pending": true,
          "points": 0,
          "reason": "Pending. Latency is measured per call by our probes, which haven't run yet, so this run doesn't score it. Its weight is shared across the assessed categories until the first probe window closes."
        },
        {
          "key": "schema",
          "name": "Schema \u0026 documentation",
          "weight": 13,
          "effectiveWeight": 16.25,
          "score": 60,
          "points": 9.75,
          "reason": "API reading. No OpenAPI file or other machine-readable description of the push API was found. The Node SDK publishes TypeScript types for messages, tickets and receipts (5 of 25). docs.expo.dev has an `llms.txt` page map and serves every page as Markdown (10). The message table gives each field's platform and its APNs or FCM equivalent, with notes on `ttl`, `priority` and `channelId`, and the page says when to call FCM and APNs directly instead (16 of 20). Fields are typed, with enums for `priority` and `interruptionLevel`, while `data` and the error `details` are free-form objects (10 of 15). curl requests, sample responses, four request error codes and five receipt error codes with fixes (13 of 15). The path carries `v2`, and the docs page shows a modification date of 25 September 2026. No changelog for the push API was found, only the Node SDK's (6 of 15)."
        },
        {
          "key": "ergonomics",
          "name": "Agent ergonomics",
          "weight": 13,
          "effectiveWeight": 16.25,
          "score": 63,
          "points": 10.24,
          "reason": "API reading. Responses are a ticket or receipt per message and nothing else, and one request carries up to 100 messages (22 of 25). Receipts are fetched by ID, up to 1,000 a request, and cleared after 24 hours. There is no call to list sent notifications and no filtering (8 of 20). Request and receipt errors have named codes with a stated fix, and per-message errors come back alongside successes (17 of 20). No idempotency key and no dry run. Retry guidance is written down and Expo says duplicates are possible (6 of 20). Only `to` is required and no credential is needed by default. Expo maintains one SDK, for Node.js, and the other twelve listed are community or Symfony libraries (10 of 15)."
        },
        {
          "key": "security",
          "name": "Security \u0026 auth",
          "weight": 14,
          "effectiveWeight": 17.5,
          "score": 48,
          "points": 8.4,
          "reason": "By default the API takes no credential, and the docs say a leaked push token lets another party send to that device. An owner can require a Bearer access token, either a personal token that acts on every account the person can reach or a robot user's token limited by role, and both can be revoked (12 of 30). Robot users take a role, but no send-only permission or confirmation step was found (6 of 20). Tickets and receipts return only status and error fields, no third-party content (10). Audit logs of administrative actions are for Enterprise subscribers, and there is no per-send log beyond receipts kept 24 hours (5 of 15). A security.txt with a disclosure address and no Expires field, bounties described as usually reserved for flaws as severe as remote code execution, and SOC 2 Type 2 for the Security criterion with the report on request (15 of 20)."
        },
        {
          "key": "payments",
          "name": "Payments \u0026 pricing",
          "weight": 10,
          "effectiveWeight": 12.5,
          "score": 40,
          "points": 5,
          "reason": "No x402, MPP or L402 (0). The push FAQ says sending costs nothing, and the pricing page is public (20). The service is free and the Free plan is $0 a month. Whether signup asks for a card was not stated (15 of 20). The send call needs no key, but a push token exists only after a person has set up an Expo account, a project and APNs and FCM credentials, and the terms bar accounts registered by agents (5 of 20)."
        },
        {
          "key": "tasks",
          "name": "Task success",
          "weight": 10,
          "effectiveWeight": 0,
          "pending": true,
          "points": 0,
          "reason": "Pending. Task success needs the category task suites run through each tool, which haven't run yet, so this run doesn't score it. Its weight is shared across the assessed categories until then. A data provider's data-quality score is published on its listing now and becomes half of this category when it's scored."
        },
        {
          "key": "maintenance",
          "name": "Maintenance \u0026 community",
          "weight": 7,
          "effectiveWeight": 8.75,
          "score": 74,
          "points": 6.48,
          "reason": "Read as a closed service with an official SDK. The Node SDK's latest tag is v7.2.0 on 24 August 2026, 46 days before the check (20 of 30). Three releases in the last 90 days, v7.0.0 on 30 July, v7.1.0 on 8 August and v7.2.0 on 24 August (20). The SDK repository shows 2 open issues and pull requests in total, with a dependency update merged on 29 September. We did not read the issue threads or test support (15 of 25). One current official SDK, for Node.js only (10 of 15). The repository runs a test workflow on every push and pull request with Renovate configured. We did not see the run results (9 of 10)."
        },
        {
          "key": "transparency",
          "name": "Transparency \u0026 trust",
          "weight": 7,
          "effectiveWeight": 8.75,
          "score": 68,
          "points": 5.95,
          "note": "editorial 60, provenance 76",
          "reason": "Closed service under Expo's terms of service, which cover every Expo service without naming push, with an MIT Node SDK (15 of 30). The FAQ says notification content is held only in memory and queues until handed to Apple or Google, the security page says push tokens are stored and the payload deleted after sending, and the privacy policy lists push tokens among data collected. These agree. No retention period for tokens and no public DPA were found (22 of 30). The docs mark `_contentAvailable` as deprecated with no removal date, and no deprecation policy was found (5 of 20). The sub-processor list, updated 15 September 2026, names each company with its country and lists Apple and Google for sending push, and the docs place the push service on Google Cloud in the United States (18 of 20)."
        }
      ],
      "assessment": {
        "date": "2026-10-09",
        "basis": "public evidence",
        "confidence": "medium",
        "notes": {
          "ergonomics": "API reading. Responses are a ticket or receipt per message and nothing else, and one request carries up to 100 messages (22 of 25). Receipts are fetched by ID, up to 1,000 a request, and cleared after 24 hours. There is no call to list sent notifications and no filtering (8 of 20). Request and receipt errors have named codes with a stated fix, and per-message errors come back alongside successes (17 of 20). No idempotency key and no dry run. Retry guidance is written down and Expo says duplicates are possible (6 of 20). Only `to` is required and no credential is needed by default. Expo maintains one SDK, for Node.js, and the other twelve listed are community or Symfony libraries (10 of 15).",
          "maintenance": "Read as a closed service with an official SDK. The Node SDK's latest tag is v7.2.0 on 24 August 2026, 46 days before the check (20 of 30). Three releases in the last 90 days, v7.0.0 on 30 July, v7.1.0 on 8 August and v7.2.0 on 24 August (20). The SDK repository shows 2 open issues and pull requests in total, with a dependency update merged on 29 September. We did not read the issue threads or test support (15 of 25). One current official SDK, for Node.js only (10 of 15). The repository runs a test workflow on every push and pull request with Renovate configured. We did not see the run results (9 of 10).",
          "payments": "No x402, MPP or L402 (0). The push FAQ says sending costs nothing, and the pricing page is public (20). The service is free and the Free plan is $0 a month. Whether signup asks for a card was not stated (15 of 20). The send call needs no key, but a push token exists only after a person has set up an Expo account, a project and APNs and FCM credentials, and the terms bar accounts registered by agents (5 of 20).",
          "reliability": "Hosted reading. status.expo.dev is a Statuspage site with a Push Notifications Broker component (20). The incident feed reaches back only to 4 August 2026, so 11 July to 3 August went unread. It lists three push incidents, an iOS push partial outage on 4 August lasting 83 minutes, delayed iOS push for an hour on 5 September and an iOS queue backlog on 8 September lasting 4 hours 41 minutes, plus wider API and website incidents on 1 September and 5 October. Read as one major incident (10). Limits are published with numbers, 600 notifications a second per project, 100 messages a request and 1,000 receipt IDs a request (15). The docs tell callers to retry 429 and 5xx with exponential backoff and the Node SDK does so twice on 429. No Retry-After header is documented and there is no idempotency key, while Expo says a notification may be handed on more than once (10 of 15). The docs state the push service has no SLA (0). The API is generally available (10).",
          "schema": "API reading. No OpenAPI file or other machine-readable description of the push API was found. The Node SDK publishes TypeScript types for messages, tickets and receipts (5 of 25). docs.expo.dev has an `llms.txt` page map and serves every page as Markdown (10). The message table gives each field's platform and its APNs or FCM equivalent, with notes on `ttl`, `priority` and `channelId`, and the page says when to call FCM and APNs directly instead (16 of 20). Fields are typed, with enums for `priority` and `interruptionLevel`, while `data` and the error `details` are free-form objects (10 of 15). curl requests, sample responses, four request error codes and five receipt error codes with fixes (13 of 15). The path carries `v2`, and the docs page shows a modification date of 25 September 2026. No changelog for the push API was found, only the Node SDK's (6 of 15).",
          "security": "By default the API takes no credential, and the docs say a leaked push token lets another party send to that device. An owner can require a Bearer access token, either a personal token that acts on every account the person can reach or a robot user's token limited by role, and both can be revoked (12 of 30). Robot users take a role, but no send-only permission or confirmation step was found (6 of 20). Tickets and receipts return only status and error fields, no third-party content (10). Audit logs of administrative actions are for Enterprise subscribers, and there is no per-send log beyond receipts kept 24 hours (5 of 15). A security.txt with a disclosure address and no Expires field, bounties described as usually reserved for flaws as severe as remote code execution, and SOC 2 Type 2 for the Security criterion with the report on request (15 of 20).",
          "transparency": "Closed service under Expo's terms of service, which cover every Expo service without naming push, with an MIT Node SDK (15 of 30). The FAQ says notification content is held only in memory and queues until handed to Apple or Google, the security page says push tokens are stored and the payload deleted after sending, and the privacy policy lists push tokens among data collected. These agree. No retention period for tokens and no public DPA were found (22 of 30). The docs mark `_contentAvailable` as deprecated with no removal date, and no deprecation policy was found (5 of 20). The sub-processor list, updated 15 September 2026, names each company with its country and lists Apple and Google for sending push, and the docs place the push service on Google Cloud in the United States (18 of 20)."
        },
        "sources": [
          {
            "what": "sending guide, read as Markdown",
            "url": "https://docs.expo.dev/push-notifications/sending-notifications.md",
            "seen": "2026-10-09"
          },
          {
            "what": "push FAQ, read as Markdown",
            "url": "https://docs.expo.dev/push-notifications/faq.md",
            "seen": "2026-10-09"
          },
          {
            "what": "programmatic access (access tokens and robot users)",
            "url": "https://docs.expo.dev/accounts/programmatic-access.md",
            "seen": "2026-10-09"
          },
          {
            "what": "docs page map",
            "url": "https://docs.expo.dev/llms.txt",
            "seen": "2026-10-09"
          },
          {
            "what": "status page components",
            "url": "https://status.expo.dev/",
            "seen": "2026-10-09"
          },
          {
            "what": "status incident feed",
            "url": "https://status.expo.dev/history.atom",
            "seen": "2026-10-09"
          },
          {
            "what": "pricing",
            "url": "https://expo.dev/pricing",
            "seen": "2026-10-09"
          },
          {
            "what": "terms of service",
            "url": "https://expo.dev/terms",
            "seen": "2026-10-09"
          },
          {
            "what": "privacy policy",
            "url": "https://expo.dev/privacy",
            "seen": "2026-10-09"
          },
          {
            "what": "security and compliance",
            "url": "https://expo.dev/security",
            "seen": "2026-10-09"
          },
          {
            "what": "sub-processor list",
            "url": "https://expo.dev/privacy/subprocessors",
            "seen": "2026-10-09"
          },
          {
            "what": "security.txt",
            "url": "https://expo.dev/.well-known/security.txt",
            "seen": "2026-10-09"
          },
          {
            "what": "product changelog",
            "url": "https://expo.dev/changelog",
            "seen": "2026-10-09"
          },
          {
            "what": "Node SDK source, tags, changelog and workflows (shallow clone, not run)",
            "url": "https://github.com/expo/expo-server-sdk-node",
            "seen": "2026-10-09"
          },
          {
            "what": "npm weekly downloads",
            "url": "https://api.npmjs.org/downloads/point/last-week/expo-server-sdk",
            "seen": "2026-10-09"
          },
          {
            "what": "domain registration (RDAP)",
            "url": "https://pubapi.registry.google/rdap/domain/expo.dev",
            "seen": "2026-10-09"
          }
        ],
        "openQuestions": [
          "unchecked: the status record from 11 July to 3 August 2026, which the incident feed no longer lists",
          "unchecked: the Expo subscription agreement, which expo.dev/robots.txt disallows",
          "unchecked: the Drata trust centre and any DPA behind it",
          "Whether signup for the Free plan asks for a card",
          "Whether 429 responses carry a Retry-After header, which the docs do not say",
          "Whether the 1 September and 5 October 2026 platform incidents affected push sends",
          "The docs give 1,000 receipt IDs a request and the Node SDK chunks at 300. Which limit the server enforces was not tested",
          "Expo's terms bar accounts registered by bots, agents or other automated means, which matters before any probe is run"
        ]
      },
      "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"
    },
    "notable": [
      "The docs say the HTTP API \"currently does not require any authentication\", and that a leaked push token lets someone else send to that device unless enhanced push security is on (https://docs.expo.dev/push-notifications/sending-notifications/)",
      "Limit of 600 notifications a second per project, 100 messages a send request and 1,000 ticket IDs a receipts request. The Node SDK asks for receipts 300 at a time (https://docs.expo.dev/push-notifications/sending-notifications/)",
      "The docs state the push service has no SLA and makes at least one attempt to hand each notification to APNs or FCM, with rare duplicates (https://docs.expo.dev/push-notifications/sending-notifications/)",
      "status.expo.dev has a Push Notifications Broker component. Its feed lists an iOS push partial outage on 4 August 2026, delayed iOS push on 5 September and an iOS queue backlog on 8 September (https://status.expo.dev/history.atom)",
      "Expo says notification content is kept only in memory and message queues until handed to Apple or Google, and that staff may see content while debugging (https://docs.expo.dev/push-notifications/faq/)",
      "The terms say accounts registered by bots, agents or other automated methods are not permitted (https://expo.dev/terms)",
      "Docs pages carry an `AgentInstructions` block addressed to AI agents that asks them to submit feedback with an npx command or an HTTP POST. We did not act on it (https://docs.expo.dev/push-notifications/sending-notifications.md)"
    ],
    "area": "everyday",
    "details": [
      {
        "label": "Endpoints",
        "value": "POST `https://exp.host/--/api/v2/push/send` and POST `https://exp.host/--/api/v2/push/getReceipts`, JSON bodies, gzip accepted"
      },
      {
        "label": "Targets",
        "value": "Expo push tokens from apps built with Expo's `expo-notifications` library. Android through FCM v1 and iOS through APNs. No web push, email or SMS"
      },
      {
        "label": "Limits",
        "value": "600 notifications a second per project, 100 messages a send request, 1,000 ticket IDs a receipts request, 4,096 bytes a payload"
      },
      {
        "label": "Receipts",
        "value": "A send returns a ticket per message. A receipt records whether APNs or FCM accepted it, is best read after 15 minutes and is cleared after 24 hours"
      },
      {
        "label": "Errors",
        "value": "Request codes `TOO_MANY_REQUESTS`, `PUSH_TOO_MANY_EXPERIENCE_IDS`, `PUSH_TOO_MANY_NOTIFICATIONS`, `PUSH_TOO_MANY_RECEIPTS` and `UNAUTHORIZED`. Receipt codes `DeviceNotRegistered`, `MessageTooBig`, `MessageRateExceeded`, `MismatchSenderId` and `InvalidCredentials`"
      },
      {
        "label": "Credentials",
        "value": "None by default. Optional enhanced push security requires a Bearer access token (personal, or a robot user's with a role)"
      },
      {
        "label": "SDKs",
        "value": "`expo-server-sdk` 7.2.0 for Node.js 22.12 or later, MIT, maintained by Expo, with six concurrent connections, gzip and two retries on 429. Twelve other libraries listed in the docs are community or Symfony maintained"
      },
      {
        "label": "Delivery",
        "value": "Best effort, at least one attempt to hand off to APNs or FCM, no SLA. Duplicates are possible and there is no idempotency key"
      },
      {
        "label": "Hosting",
        "value": "Google Cloud Platform in the United States, per the docs"
      },
      {
        "label": "Certifications",
        "value": "SOC 2 Type 2 for the Security criterion, report on request for Production and Enterprise customers, per expo.dev/security"
      },
      {
        "label": "Status",
        "value": "status.expo.dev on Statuspage with a Push Notifications Broker component"
      }
    ],
    "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,
      "checks": [
        {
          "check": "Legal entity named",
          "value": "650 Industries, Inc.",
          "points": 20,
          "max": 20,
          "state": "ok"
        },
        {
          "check": "Domain age",
          "value": "expo.dev, registered 2019-02-22 (7 years)",
          "points": 11,
          "max": 15,
          "state": "part"
        },
        {
          "check": "Endpoint on the vendor's domain",
          "value": "exp.host is not on expo.dev",
          "points": 0,
          "max": 15,
          "state": "no"
        },
        {
          "check": "Terms of service",
          "value": "read, states 7 of the 7 things a reader expects, and has 2 clauses that cost points",
          "points": 6,
          "max": 10,
          "state": "part"
        },
        {
          "check": "Privacy policy",
          "value": "read, states 6 of the 8 things a reader expects",
          "points": 8.5,
          "max": 10,
          "state": "part"
        },
        {
          "check": "Status page",
          "value": "status.expo.dev",
          "points": 10,
          "max": 10,
          "state": "ok"
        },
        {
          "check": "Changelog",
          "value": "published",
          "points": 10,
          "max": 10,
          "state": "ok"
        },
        {
          "check": "security.txt",
          "value": "valid",
          "points": 10,
          "max": 10,
          "state": "ok"
        }
      ],
      "policies": [
        {
          "kind": "terms",
          "url": "https://expo.dev/terms",
          "state": "read",
          "readAt": "2026-10-09",
          "statedDate": "2025-05-29",
          "words": 7916,
          "points": 6,
          "max": 10,
          "expected": [
            {
              "key": "terms.date",
              "label": "Gives the date it was last updated",
              "found": true,
              "quote": "Last updated May 29, 2025, and effective June 30, 2025.",
              "says": "Last updated 2025-05-29"
            },
            {
              "key": "terms.law",
              "label": "Names the governing law or courts",
              "found": true,
              "quote": "These Terms shall be governed by, and construed and interpreted in accordance with, the laws of the State of California (without giving effect to conflict of law principles).",
              "says": "The law of the State of California"
            },
            {
              "key": "terms.liability",
              "label": "States a limit on its liability",
              "found": true,
              "quote": "To the fullest extent permitted by law, in no event shall the Expo Parties’ total liability to you for all damages, losses and causes of action, whether in contract, tort (including negligence) or otherwise exceed the greater of the actual amount you paid for the services (if any) and $100, except to the extent an app…",
              "says": "Capped at $100,"
            },
            {
              "key": "terms.termination",
              "label": "Says how the agreement or account can be ended",
              "found": true,
              "quote": "If you knowingly give false, misleading, or inaccurate information regarding the existence of infringing content, we may suspend your account, and you may face other legal consequences."
            },
            {
              "key": "terms.changes",
              "label": "Says how changes to the terms are announced",
              "found": true,
              "quote": "…mail to the attention of the Legal Department at 624 University Ave, FL1, Palo Alto CA 94301 and by email to legal@expo.dev within 30 days of the date such change became effective, as indicated by the later of (a) the “Last Updated” date of the Terms you seek to reject or (b) the date of our email to you notifying you…",
              "says": "Gives 30 days of notice before a change"
            },
            {
              "key": "terms.use",
              "label": "Lists what users may not do",
              "found": true,
              "quote": "If you do not have authority to or do not agree to all of these Terms, or if you object to the Privacy Policy, you must not access or use the Services."
            },
            {
              "key": "terms.sla",
              "label": "Refers to a service level or uptime commitment",
              "found": true,
              "quote": "You acknowledge and agree that all use of any Beta Feature is at your sole risk, and that warranties, indemnities and SLA terms do not apply."
            }
          ],
          "toKnow": [
            {
              "key": "terms.automated",
              "label": "Restricts automated access",
              "found": true,
              "quote": "Accounts registered by “bots,” “agents,” or other automated methods or means are not permitted.",
              "costsPoints": true
            },
            {
              "key": "terms.nonotice",
              "label": "Says the terms or the service can change without notice",
              "found": true,
              "quote": "Expo reserves the right to permanently or temporarily modify or remove the Services or any portion thereof (including without limitation by changing the user interface of or removing certain features from the Services) from time to time, in Expo’s sole discretion, without notice to you.",
              "costsPoints": true
            },
            {
              "key": "terms.cutoff",
              "label": "Says access can be ended without notice or for any reason",
              "found": true,
              "quote": "Expo may immediately terminate these Terms with you and suspend or terminate your access to the Services for any or no reason at any time without notice, including, without limitation, if you fail to comply with any provision of these Terms, our Acceptable Use Policy, or our Community Guidelines."
            },
            {
              "key": "terms.arbitration",
              "label": "Requires arbitration or waives class actions",
              "found": true,
              "quote": "BY AGREEING TO BINDING ARBITRATION, YOU WAIVE YOUR RIGHT TO LITIGATE DISPUTES THROUGH A COURT AND TO HAVE A JUDGE OR JURY DECIDE YOUR CASE."
            }
          ],
          "notes": [
            {
              "date": "2026-10-08",
              "text": "Total liability is capped at the greater of the amount paid for the services and 100 US dollars.",
              "quote": "in no event shall the Expo Parties’ total liability to you for all damages, losses and causes of action, whether in contract, tort (including negligence) or otherwise exceed the greater of the actual amount you paid for the services (if any) and $100"
            },
            {
              "date": "2026-10-08",
              "text": "A login may be used by one person only, and it may not be shared with any other person or entity.",
              "quote": "You may not share or otherwise permit any other person or entity to access the Services using your username and password."
            },
            {
              "date": "2026-10-08",
              "text": "The customer authorises Expo to use its name or logo in marketing and promotional materials.",
              "quote": "You authorize Expo to use your name or logo to refer to you as a customer of the Services in connection with Expo’s marketing and promotional materials."
            }
          ]
        },
        {
          "kind": "privacy",
          "url": "https://expo.dev/privacy",
          "state": "read",
          "readAt": "2026-10-09",
          "statedDate": "2025-10-21",
          "words": 3283,
          "points": 8.5,
          "max": 10,
          "expected": [
            {
              "key": "privacy.date",
              "label": "Gives the date it was last updated",
              "found": true,
              "quote": "Last updated October 21st 2025",
              "says": "Last updated 2025-10-21"
            },
            {
              "key": "privacy.collected",
              "label": "Says what personal data is collected",
              "found": true,
              "quote": "Expo is committed to protecting the privacy and security of the information we collect and to being transparent about the ways in which we collect and process your information."
            },
            {
              "key": "privacy.retention",
              "label": "Says how long data is kept",
              "found": false
            },
            {
              "key": "privacy.processors",
              "label": "Says who else receives the data",
              "found": true,
              "quote": "For example, if you access any social media or similar services through the Services to login or to share information about your experience on our Services with others, we may collect information from these third-party services."
            },
            {
              "key": "privacy.sale",
              "label": "Says whether personal data is sold or shared for advertising",
              "found": false
            },
            {
              "key": "privacy.rights",
              "label": "Says what rights people have over their data",
              "found": true,
              "quote": "Pursuant to the Data Privacy Framework, EU, UK, and Swiss individuals have the right to obtain our confirmation of whether we maintain personal information relating to you in the United States, and the right to access that data."
            },
            {
              "key": "privacy.contact",
              "label": "Gives a privacy contact",
              "found": true,
              "quote": "EU, UK, and Swiss individuals with Data Privacy Framework inquiries or complaints should first contact us via our contact form."
            },
            {
              "key": "privacy.transfers",
              "label": "Says where data is transferred or stored",
              "found": true,
              "quote": "…confidentiality, and, to the extent required by applicable law, the Company implements measures such as standard contractual clauses or other appropriate legal mechanisms to ensure that any transferred information remains protected and secure.",
              "says": "Relies on standard contractual clauses"
            }
          ],
          "notes": [
            {
              "date": "2026-10-08",
              "text": "Deleting an account removes all past and active work associated with it and cannot be reversed.",
              "quote": "Account deletions include any and all past and active work associated with the account, and are irreversible."
            }
          ]
        }
      ]
    },
    "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-10T01:37:51.355353289Z",
        "lastOk": true,
        "lastStatus": 405,
        "lastMs": 143,
        "authRequired": false,
        "uptime24h": 100,
        "uptime30d": 100,
        "p50ms24h": 128,
        "p95ms24h": 192,
        "samples24h": 102,
        "samples30d": 102,
        "days": [
          {
            "date": "2026-10-09",
            "probes": 85,
            "ok": 85
          },
          {
            "date": "2026-10-10",
            "probes": 17,
            "ok": 17
          }
        ]
      },
      "vendorStatus": {
        "page": "https://status.expo.dev",
        "indicator": "none",
        "summary": "All Systems Operational",
        "checkedAt": "2026-10-10T01:33:41.378077992Z"
      },
      "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-10T01:37:51.355353289Z"
    }
  }
}
