generated: '2026-08-13' method: searched source: >- openapi/_original/plunk-api-openapi.json, https://docs.useplunk.com/api-reference/overview, https://docs.useplunk.com/guides/idempotency, https://www.useplunk.com/privacy note: >- Conformance asserted against what Plunk actually ships. Negative findings are as deliberate as positive ones: this is a bearer-API-key platform with no OAuth surface, and its error envelope is bespoke rather than RFC 9457. standards: - id: openapi-3.1 conforms: true evidence: 'https://docs.useplunk.com/openapi.json declares openapi 3.1.0 with 9 paths / 15 operations, all with operationIds, summaries, tags, request/response schemas, examples and reusable components.' - id: oauth2 conforms: false evidence: 'The only securityScheme is ApiKeyAuth (http bearer, bearerFormat "API Key"). Dashboard sign-in offers GitHub/Google OAuth (GET /auth/oauth-config), but that is human login to the console, not API authorization. No scopes surface exists — see scopes/ deliberately omitted.' - id: oidc conforms: false evidence: '/.well-known/openid-configuration returns 404 on every Plunk host.' - id: rfc6750-bearer-token conforms: true evidence: 'Credentials are presented as Authorization: Bearer on every request, per https://docs.useplunk.com/guides/api-keys.' - id: rfc9457-problem-details conforms: false evidence: 'Errors are application/json in a bespoke {success:false, error:{code,message,statusCode,requestId,errors,details,suggestion}, timestamp} envelope, not application/problem+json. Richer than RFC 9457 requires in content, but not the registered media type. See errors/plunk-problem-types.yml.' - id: idempotency-key conforms: true partial: true evidence: 'Idempotency-Key request header declared as #/components/parameters/IdempotencyKey on POST /v1/send and POST /v1/track; documented at https://docs.useplunk.com/guides/idempotency. Project-scoped, 1-255 printable ASCII, 24h TTL.' deviation: >- Diverges from the draft-ietf-httpapi-idempotency-key-header semantics and from the prevailing Stripe-style implementation: Plunk REFUSES a reused key with 409 IDEMPOTENCY_KEY_REUSED rather than REPLAYING the original response. A caller therefore cannot recover the original resource ID from a retry. It is a genuine at-most-once guarantee, but it is not a safe-retry primitive. - id: cursor-pagination conforms: true evidence: 'limit/cursor query parameters and {data, cursor, hasMore, total} response envelope, declared in components.parameters and documented in the API reference. A second, page-based style (page/pageSize) applies to GET /segments/{id}/contacts.' - id: rfc9116-security-txt conforms: false evidence: '/.well-known/security.txt returns 404 on all four Plunk hosts. See well-known/plunk-well-known.yml.' - id: rfc8594-sunset-header conforms: false evidence: 'No Sunset or Deprecation header support and no deprecation policy is published. See lifecycle/plunk-lifecycle.yml.' - id: rfc9110-rate-limit-headers conforms: false evidence: 'The documented limit is 1000 req/min per project with a 429 on exhaustion, but no RateLimit-*, X-RateLimit-* or Retry-After response header is documented. An agent cannot read remaining budget at runtime.' - id: rfc8058-one-click-unsubscribe conforms: true evidence: 'One-click POST unsubscribe links for Plunk-hosted emails shipped in v0.13.0 (2026-08-09); List-Unsubscribe is emitted in the header section (v0.10.0, 2026-05-01).' - id: json-api conforms: false evidence: 'Plunk uses plain JSON with two different envelopes by route family (wrapped for /v1/*, bare resource for dashboard routes). Not JSON:API.' - id: graphql conforms: false evidence: 'No /graphql surface on any Plunk host.' - id: grpc conforms: false evidence: 'No .proto definitions in the useplunk GitHub organization or on buf.build.' - id: asyncapi conforms: false evidence: 'No AsyncAPI document is published. A documented webhook event catalogue exists instead — see asyncapi/plunk-webhooks.yml.' - id: webhook-signing conforms: false evidence: 'Plunk does not sign outbound webhook payloads. Authenticity is left to a caller-configured shared-secret header. No HMAC, no timestamp, no replay protection.' - id: mcp conforms: false evidence: 'No first-party MCP server. See mcp/plunk-mcp.yml.' - id: a2a conforms: false evidence: 'No agent card at /.well-known/agent-card.json or /.well-known/agent.json on any host.' - id: llms-txt conforms: true evidence: 'Served at both https://www.useplunk.com/llms.txt and https://docs.useplunk.com/llms.txt (200), each a well-formed llms.txt with H1, blockquote summary and sectioned link lists. The docs variant explicitly links the OpenAPI.' - id: markdown-content-negotiation conforms: true evidence: >- Every documentation page is available as Markdown by appending .md or sending Accept: text/markdown, on both the marketing site and the docs site. API reference pages render the OpenAPI operation into the Markdown response. Shipped in v0.9.0/v0.10.0. This is a deliberate, working agent-readable documentation surface — rarer than llms.txt and more useful. - id: gdpr conforms: true evidence: 'https://www.useplunk.com/privacy is structured around GDPR — data controller identification, lawful bases for processing, data subject rights, sub-processor disclosure (AWS SES under an AWS DPA and Standard Contractual Clauses, Stripe), retention schedule. A standalone DPA is published at https://www.useplunk.com/dpa.' - id: soc2 conforms: false evidence: 'No SOC 2 claim anywhere on the site; no trust center (trust.useplunk.com does not resolve).' - id: iso-27001 conforms: false evidence: 'No ISO 27001 claim published.' - id: hipaa conforms: false evidence: 'No HIPAA claim or BAA offer published.' - id: agpl-3.0-open-source conforms: true evidence: 'github.com/useplunk/plunk is AGPL-3.0 with 5,363 stars and a Docker Compose self-hosting path; the hosted service and the self-hosted distribution are the same codebase.' compliance_program: published: true kind: regulatory certifications: [] documents: - {name: Privacy Policy, url: 'https://www.useplunk.com/privacy', covers: [GDPR lawful bases, data subject rights, sub-processors, retention, email tracking, cookies]} - {name: Data Processing Agreement, url: 'https://www.useplunk.com/dpa'} - {name: Terms of Service, url: 'https://www.useplunk.com/terms'} - {name: Data Retention schedule, url: 'https://docs.useplunk.com/guides/data-retention'} sub_processors: - {name: AWS SES, role: email delivery, region: eu-north-1, protection: AWS DPA and Standard Contractual Clauses, note: 'Region read from the unauthenticated https://next-api.useplunk.com/config document.'} - {name: Stripe, role: billing and payments} note: >- Plunk publishes a real, specific compliance program — GDPR posture, a DPA, a named sub-processor list, and a dated retention schedule — but holds NO third-party certifications. Recorded as a compliance program, not as certification. Self-hosting is offered explicitly as the data-residency answer in place of certification. summary: asserted: 24 conforms_true: 9 conforms_false: 15 certifications: 0