v1 is live. One endpoint. One job. Read the quickstart →
vipvap docs · v1

The quickstart.

You have a single endpoint to send OTP emails. Here's the entire integration.

1. Sign up and grab your API key

Open the sign-up page, create an account, and the dashboard shows your first API key — a one-time reveal.

2. Send your first OTP

Hit POST /v1/send with a Bearer key and a JSON body.

curl -X POST https://api.vipvap.xyz/v1/send \
  -H "Authorization: Bearer vp_live_a4f2…" \
  -H "Content-Type: application/json" \
  -d '{
    "recipient": "alice@acme.com",
    "code":      "418917"
  }'

Response

// 200 OK
{
  "id":      "snd_3f2a9b",
  "status":  "delivered",
  "to":      "alice@acme.com",
  "from":    "vipvap <notify@vipvap.xyz>",
  "subject": "vipvap: your verification code",
  "expires_in_minutes": 10,
  "quota_remaining":    1949
}

API reference

POST
/v1/send
Send one OTP email. Authenticated by Bearer key.
GET
/v1/usage
Current period usage and quota remaining.

POST /v1/send

Request body

FieldTypeRequiredDescription
recipientstringrequiredRecipient email address.
codestringrequiredThe OTP. 4–12 chars; whatever your flow expects.
countrystringoptionalISO 3166-1 alpha-2 country for the recipient (e.g. "US"). Powers the Countries analytics and the country filter in Send logs. Omit it and vipvap falls back to the request's geolocation header, then to unknown.

Response — 200

FieldTypeDescription
idstringSend ID, used by the dashboard logs.
statusstringdelivered, queued, bounced, failed.
tostringRecipient address.
fromstringRendered From line. Always vipvap <notify@vipvap.xyz>.
subjectstringRendered subject line. Always vipvap: your verification code.
expires_in_minutesintegerDefault expiry applied to the message body.
quota_remainingintegerHard cap minus used, after this send.

Errors

StatuscodeWhat it means
401invalid_api_keyMissing or wrong Bearer token.
400invalid_recipientAddress is malformed.
400invalid_codeCode is missing or wrong shape.
429quota_exceededHard cap reached. No overages — upgrade in the dashboard to lift it.

Country detection

Every send is tagged with the recipient's country so you can see where your OTPs go. vipvap resolves it in this order and never guesses:

  1. The country you pass in the request (or an X-Country header), if it is a valid ISO alpha-2 code.
  2. A geolocation header set by the proxy/CDN in front of your vipvap instance — CF-IPCountry, X-Vercel-IP-Country, X-AppEngine-Country, X-Country-Code or X-Geo-Country.
  3. Otherwise unknown. A send with no location signal is labelled unknown, never a wrong country.

The dashboard's Countries view maps each country that received OTPs, darker and larger where more codes went, with per-country volume and delivery rate over Today / 7 days / 30 days / all time. Send logs show the country per row and can be filtered to one country.

Webhooks

Set a webhook URL in the dashboard's Settings page and we'll POST delivery status callbacks as a single vipvap-delivery event.

{
  "event": "vipvap.delivery",
  "data": {
    "id":         "snd_3f2a9b",
    "status":     "delivered",
    "recipient":  "alice@acme.com"
  }
}

Contact

Need a higher quota, a separate sending segment, or a custom agreement? Email hi@vipvap.xyz.