DocumentationReference
Built-in Verification

Provider Coverage

ReplaySafe verifies UNKNOWN side effects by querying provider APIs directly. Each provider verifier classifies failures as either TRANSIENT (safe to retry) or SEMANTIC (needs human review).

Built-in Providers

💳

Stripe

Payments

Verify Method

GET /v1/charges/:id

TRANSIENT (safe to retry)

network timeout429 rate limit

SEMANTIC (needs review)

card declinedinsufficient fundscharge disputed
📧

SendGrid

Email

Verify Method

GET /v3/messages/:id

TRANSIENT (safe to retry)

API timeout503 service unavailable

SEMANTIC (needs review)

mailbox fullinvalid emailbounced
📮

Postmark

Email

Verify Method

GET /messages/outbound/:id/details

TRANSIENT (safe to retry)

connection timeout429 rate limit

SEMANTIC (needs review)

bouncedsuppressedspam complaint
📬

AWS SES

Email

Verify Method

Check receipt.status field

TRANSIENT (safe to retry)

throttlingtemporary failure

SEMANTIC (needs review)

permanent bouncesuppressedinvalid recipient
🐙

GitHub

Dev Tools

Verify Method

GET /repos/:owner/:repo/issues/:id

TRANSIENT (safe to retry)

rate limit (403)API timeout

SEMANTIC (needs review)

issue not foundrepo deletedpermission denied
💬

Slack

Messaging

Verify Method

GET /conversations.info

TRANSIENT (safe to retry)

rate limit (429)network error

SEMANTIC (needs review)

channel not foundtoken revokeduser not in channel
📱

Twilio

SMS / Voice

Verify Method

GET /2010-04-01/Accounts/:sid/Messages/:sid.json

TRANSIENT (safe to retry)

API timeout503 service unavailable

SEMANTIC (needs review)

invalid numberundeliveredfailed
🪣

AWS S3

Storage

Verify Method

HEAD /:bucket/:key

TRANSIENT (safe to retry)

connection timeout503 slow down

SEMANTIC (needs review)

access deniedbucket not foundobject not found

Failure Classification

Every provider verifier classifies failures into two categories. This classification drives the Recovery Engine's decisions.

TRANSIENT

Temporary failures that are safe to retry automatically. The operation may or may not have succeeded.

Network timeouts
Rate limiting (429)
Service unavailable (503)

SEMANTIC

The operation completed but returned a wrong or stale result. Retrying blindly will produce the same outcome.

Card declined
Email bounced
Resource not found

Custom Verifiers

Need to verify against a provider not listed above? Register a custom verifier.

import { verifierRegistry } from '@replaysafe/guard-sdk'

class MyCustomVerifier {
  provider = 'my-provider'

  async verify(entry) {
    const response = await fetch(`https://api.my-provider.com/status/${entry.receipt.id}`)
    const data = await response.json()

    if (data.status === 'delivered') {
      return { status: 'VERIFIED' }
    }
    if (data.status === 'bounced') {
      return { status: 'FAILED', failureType: 'SEMANTIC' }
    }
    return { status: 'UNKNOWN' }
  }
}

verifierRegistry.register(new MyCustomVerifier())

Adding New Providers

To add a new built-in provider verifier, implement the Verifier interface and register it in the VerificationService. See the existing verifiers in apps/api/src/services/verifiers/ for reference.