Integrations — Supabase, Cloudflare Workers, Next.js, Node, Python

SignupDoggy integrates with everything: Supabase Auth, Cloudflare Workers, Next.js, Express, FastAPI, Django, and more. Working code for each, plus the 2-stage funnel pattern.

SignupDoggy integrations

SignupDoggy integrates with everything. Here is the working code for each common platform.

SUPABASE AUTH (recommended)

The cleanest pattern: a Postgres trigger on auth.users. The trigger fires before each new user is created, calls SignupDoggy, and raises an exception if the recommendation is 'block'.

```sql
create or replace function public.check_signup_quality()
returns trigger as $
declare
  result jsonb;
begin
  select body into result from http_post(
    'https://signupdoggy-api.jeffrinjames99.workers.dev/v1/check',
    jsonb_build_object('email', new.email, 'ip', coalesce(new.raw_user_meta_data->>'ip', '0.0.0.0')),
    'application/json',
    jsonb_build_object('X-API-KEY', current_setting('app.signupdoggy_key'))
  );

  if result->>'recommendation' = 'block' then
    raise exception 'Signup blocked: high risk signal';
  end if;

  return new;
end;
$ language plpgsql;

create trigger check_signup_quality_trigger
  before insert on auth.users
  for each row execute function public.check_signup_quality();
```

Full tutorial: /blog/signup-validation-supabase-auth-integration.

CLOUDFLARE WORKERS

```js
// In your signup Worker
const result = await fetch('https://signupdoggy-api.jeffrinjames99.workers.dev/v1/check', {
  method: 'POST',
  headers: { 'X-API-KEY': env.SIGNUPDOGGY_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({ email, ip }),
}).then(r => r.json());

if (result.recommendation === 'block') {
  return new Response('Invalid signup', { status: 400 });
}
```

NEXT.JS

Add to your API route:

```js
// pages/api/signup.js or app/api/signup/route.js
const result = await fetch('https://signupdoggy-api.jeffrinjames99.workers.dev/v1/check', {
  method: 'POST',
  headers: { 'X-API-KEY': process.env.SIGNUPDOGGY_KEY, 'Content-Type': 'application/json' },
  body: JSON.stringify({ email, ip: req.headers['x-forwarded-for'] }),
}).then(r => r.json());

if (result.recommendation === 'block') {
  return res.status(400).json({ error: 'Invalid signup' });
}
```

NODE.JS / EXPRESS

```js
app.post('/signup', async (req, res) => {
  const { email } = req.body;
  const ip = req.headers['x-forwarded-for'] || req.socket.remoteAddress;

  const result = await fetch('https://signupdoggy-api.jeffrinjames99.workers.dev/v1/check', {
    method: 'POST',
    headers: { 'X-API-KEY': process.env.SIGNUPDOGGY_KEY, 'Content-Type': 'application/json' },
    body: JSON.stringify({ email, ip }),
  }).then(r => r.json());

  if (result.recommendation === 'block') {
    return res.status(400).json({ error: 'Invalid signup' });
  }

  // proceed with signup
});
```

Full tutorial: /blog/disposable-email-detection-nodejs-tutorial.

PYTHON / FASTAPI

```python
import httpx
from fastapi import FastAPI, Request

app = FastAPI()

@app.post('/signup')
async def signup(request: Request):
    data = await request.json()
    email = data['email']
    ip = request.headers.get('x-forwarded-for', '')

    async with httpx.AsyncClient() as client:
        result = await client.post(
            'https://signupdoggy-api.jeffrinjames99.workers.dev/v1/check',
            headers={'X-API-KEY': 'sd_your_key_here'},
            json={'email': email, 'ip': ip},
        ).json()

    if result['recommendation'] == 'block':
        return {'error': 'Invalid signup'}, 400

    # proceed with signup
```

DJANGO

```python
import httpx
from django.http import JsonResponse

def signup(request):
    email = request.POST.get('email')
    ip = request.META.get('HTTP_X_FORWARDED_FOR', '')

    result = httpx.post(
        'https://signupdoggy-api.jeffrinjames99.workers.dev/v1/check',
        headers={'X-API-KEY': settings.SIGNUPDOGGY_KEY},
        json={'email': email, 'ip': ip},
    ).json()

    if result['recommendation'] == 'block':
        return JsonResponse({'error': 'Invalid signup'}, status=400)
```

CLOUDFLARE TURNSTILE + SIGNUPDOGGY (the 2-stage funnel)

Use Turnstile for the first stage (catches 95% of browser bots), SignupDoggy for the second stage (catches the remaining 5% + non-browser bots).

Full tutorial: /blog/cloudflare-turnstile-vs-server-side-fraud-api.

AUTH0

Use a Post-Login Action or Pre-User-Creation Action. Call SignupDoggy with the email and IP from the action's event object.

CLERK

Use a beforeUserCreate webhook. Call SignupDoggy with the email_address and IP from the event payload.

CURL

```bash
curl -X POST https://signupdoggy-api.jeffrinjames99.workers.dev/v1/check \
  -H "X-API-KEY: sd_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "ip": "1.2.3.4"}'
```

That is the entire API surface. One endpoint, three parameters (email, ip, phone), one response.

See /docs for the full API reference.