Sign in to fill these examples with your own keys. Sign in Start free trial

ShieldShiba

Bot checks for signup and contact forms.

Bot checks for your signup and contact forms. Each site has a public site key for the widget and a secret key for your server. secret_key is returned on create, show, and rotate_secret, not on index or update. allowed_hostnames also takes a comma or space separated string. Subdomains of an allowed hostname pass. block_hosting blocks traffic from hosting and datacenter networks. block_free_email blocks free mailbox providers. allowlist holds IPs, CIDR ranges, email domains, and email addresses that skip every check; it takes an array or a comma, space, or newline separated string, and an update replaces the whole list. A visitor who matches passes with reasons ["allowlisted"]. verifications_7d counts passed and blocked checks over the last 7 days. Redeem a widget token from your server with POST /shield/v1/verify.

GET /api/v1/teams/:obfuscated_team_id/shield_sites

List sites. secret_key is omitted.

request.sh
1curl -sS -X GET \ 2 -H 'Authorization: Bearer YOUR_API_KEY' \ 3 https://app.postshiba.com/api/v1/teams/KjkAJW/shield_sites
response.json
1[ 2 { 3 "id": "ShLdSt", 4 "name": "Signup", 5 "public_key": "ss_pk_7Fm2Qx9Lt4Wd8Nc1Hv6Bs3Kz", 6 "allowed_hostnames": [ 7 "acme.com", 8 "app.acme.com" 9 ], 10 "block_hosting": true, 11 "block_free_email": false, 12 "allowlist": [ 13 "203.0.113.7", 14 "partner.example" 15 ], 16 "verifications_7d": { 17 "passed": 128, 18 "blocked": 9 19 }, 20 "created_at": "2026-09-23T00:00:00Z" 21 } 22]

GET /api/v1/shield_sites/:id

Get one site, including the secret key.

  • id: Public site id
request.sh
1curl -sS -X GET \ 2 -H 'Authorization: Bearer YOUR_API_KEY' \ 3 https://app.postshiba.com/api/v1/shield_sites/:shield_site_id
response.json
1{ 2 "id": "ShLdSt", 3 "name": "Signup", 4 "public_key": "ss_pk_7Fm2Qx9Lt4Wd8Nc1Hv6Bs3Kz", 5 "allowed_hostnames": [ 6 "acme.com", 7 "app.acme.com" 8 ], 9 "block_hosting": true, 10 "block_free_email": false, 11 "allowlist": [ 12 "203.0.113.7", 13 "partner.example" 14 ], 15 "verifications_7d": { 16 "passed": 128, 17 "blocked": 9 18 }, 19 "created_at": "2026-09-23T00:00:00Z", 20 "secret_key": "ss_sk_2w9Qh4Lk8Xz1Vn6Rb3Tm7Pc5" 21}

POST /api/v1/teams/:obfuscated_team_id/shield_sites

Create a site. Returns the public and secret keys.

request.sh
1curl -sS -X POST \ 2 -H 'Authorization: Bearer YOUR_API_KEY' \ 3 -H 'Content-Type: application/json' \ 4 -d '{"shield_site":{"name":"Signup","allowed_hostnames":"acme.com, app.acme.com","block_hosting":true,"block_free_email":false}}' \ 5 https://app.postshiba.com/api/v1/teams/KjkAJW/shield_sites
response.json
1{ 2 "id": "ShLdSt", 3 "name": "Signup", 4 "public_key": "ss_pk_7Fm2Qx9Lt4Wd8Nc1Hv6Bs3Kz", 5 "allowed_hostnames": [ 6 "acme.com", 7 "app.acme.com" 8 ], 9 "block_hosting": true, 10 "block_free_email": false, 11 "allowlist": [ 12 "203.0.113.7", 13 "partner.example" 14 ], 15 "verifications_7d": { 16 "passed": 128, 17 "blocked": 9 18 }, 19 "created_at": "2026-09-23T00:00:00Z", 20 "secret_key": "ss_sk_2w9Qh4Lk8Xz1Vn6Rb3Tm7Pc5" 21}

PATCH /api/v1/shield_sites/:id

Update name, allowed_hostnames, block_hosting, block_free_email, or allowlist. secret_key is omitted.

  • id: Public site id
request.sh
1curl -sS -X PATCH \ 2 -H 'Authorization: Bearer YOUR_API_KEY' \ 3 -H 'Content-Type: application/json' \ 4 -d '{"shield_site":{"block_free_email":true}}' \ 5 https://app.postshiba.com/api/v1/shield_sites/:shield_site_id
response.json
1{ 2 "id": "ShLdSt", 3 "name": "Signup", 4 "public_key": "ss_pk_7Fm2Qx9Lt4Wd8Nc1Hv6Bs3Kz", 5 "allowed_hostnames": [ 6 "acme.com", 7 "app.acme.com" 8 ], 9 "block_hosting": true, 10 "block_free_email": true, 11 "allowlist": [ 12 "203.0.113.7", 13 "partner.example" 14 ], 15 "verifications_7d": { 16 "passed": 128, 17 "blocked": 9 18 }, 19 "created_at": "2026-09-23T00:00:00Z" 20}

POST /api/v1/shield_sites/:id/rotate_secret

Issue a new secret key. The old one stops working at once. The site key is unchanged.

  • id: Public site id
request.sh
1curl -sS -X POST \ 2 -H 'Authorization: Bearer YOUR_API_KEY' \ 3 -H 'Content-Type: application/json' \ 4 https://app.postshiba.com/api/v1/shield_sites/:shield_site_id/rotate_secret
response.json
1{ 2 "id": "ShLdSt", 3 "name": "Signup", 4 "public_key": "ss_pk_7Fm2Qx9Lt4Wd8Nc1Hv6Bs3Kz", 5 "allowed_hostnames": [ 6 "acme.com", 7 "app.acme.com" 8 ], 9 "block_hosting": true, 10 "block_free_email": false, 11 "allowlist": [ 12 "203.0.113.7", 13 "partner.example" 14 ], 15 "verifications_7d": { 16 "passed": 128, 17 "blocked": 9 18 }, 19 "created_at": "2026-09-23T00:00:00Z", 20 "secret_key": "ss_sk_8Jd3Ns5Wq1Yf7Kt2Gx9Hr4Lb" 21}

DELETE /api/v1/shield_sites/:id

Delete a site. Widgets using its site key stop passing.

  • id: Public site id
request.sh
1curl -sS -X DELETE \ 2 -H 'Authorization: Bearer YOUR_API_KEY' \ 3 https://app.postshiba.com/api/v1/shield_sites/:shield_site_id

POST https://app.postshiba.com/shield/v1/verify

Redeem a widget token from your server. No API key. Send the site's secret key, the token, and optionally the email the visitor typed. A token redeems once and expires after 5 minutes. 401 invalid_secret. 422 invalid_token.

request.sh
1curl -sS -X POST \ 2 -H 'Authorization: Bearer YOUR_API_KEY' \ 3 -H 'Content-Type: application/json' \ 4 -d '{"secret":"ss_sk_2w9Qh4Lk8Xz1Vn6Rb3Tm7Pc5","token":"widget-token","email":"jane@acme.com"}' \ 5 https://app.postshiba.com/shield/v1/verify
response.json
1{ 2 "success": true, 3 "verdict": "good_boy", 4 "reasons": [], 5 "email": "jane@acme.com", 6 "hostname": "acme.com", 7 "created_at": "2026-09-23T00:00:00Z" 8}