Forwarding Submissions from Third-Party Tools
Send submissions to Basin from server-side tools while preserving spam protection and authentication.
When a user submits a form on your website, Basin normally receives the submission directly from the user's browser. Basin reads the request's IP address, Origin, Referer, and User-Agent headers to power its spam filters and submission metadata.
However, some tools — like Contact Form 7 with CF7 Webhooks, Gravity Forms, or a custom server-side proxy — submit data to Basin on behalf of the user. In these cases, the request originates from a web server, not the user's browser. Basin would see the server's IP address instead of the real user's IP, which breaks spam detection and may cause legitimate submissions to be flagged.
Basin's inbound submission headers solve this by letting you pass the original user context along with the forwarded request.
Supported Headers
Basin reads two categories of headers on inbound submissions: its own custom headers for authentication and IP override, and standard HTTP headers for origin metadata.
Basin-Specific Headers
| Header | Description |
|---|---|
Basin-API-Key |
Required for IP override. Your Basin API key, used to authenticate the forwarded request. |
Basin-True-Client-IP |
The real IP address of the user who submitted the form. Basin uses this for spam filtering instead of the server's IP. |
Authentication is required for IP override
Basin-True-Client-IP is only trusted when accompanied by a valid Basin-API-Key header that matches the form's API key or the account API key. Without authentication, Basin ignores the header and falls back to request.remote_ip.
Standard HTTP Headers
These are regular HTTP headers — not Basin-specific — that Basin reads normally from the request. Your third-party tool should forward them from the original browser request so Basin records accurate submission metadata.
| Header | Description |
|---|---|
Origin |
The origin of the page hosting the form. Used by Basin to validate allowed domains. |
Referer |
The full URL of the page the user submitted from. |
User-Agent |
The user's browser user agent string. Used for bot detection. |
Choosing Your API Key
Basin supports two types of API keys. For inbound submission forwarding, we recommend the Form API Key:
| Key Type | Scope | Where to Find |
|---|---|---|
| Form API Key (recommended) | Single form only | Form Dashboard → Integrations → API |
| Account API Key | All forms in your account | Account Settings → API Settings |
Using the Form API Key limits the blast radius if the key is ever exposed — it can only be used to submit to that one form.
How to Configure Headers
The exact steps depend on your third-party tool, but the general pattern is the same: when configuring the outbound webhook or HTTP request to Basin, add the following headers:
Basin-API-Key: YOUR_FORM_API_KEY
Basin-True-Client-IP: {user_ip_variable}
Origin: {page_url_variable}
Referer: {page_url_variable}
User-Agent: {user_agent_variable}
Replace YOUR_FORM_API_KEY with your actual key, and map the remaining values to the dynamic variables your tool provides for the submitting user's context.
Integration Examples
Contact Form 7 (CF7 Webhooks plugin)
The CF7 Webhooks plugin for WordPress lets you forward Contact Form 7 submissions to any HTTP endpoint — including Basin.
Step 1: Install the plugins
Make sure both Contact Form 7 and CF7 Webhooks are installed and active on your WordPress site.
Step 2: Point the webhook at your Basin endpoint
- In WordPress, go to Contact → Contact Forms and open your form.
- Click the Webhook tab.
- Enter your Basin form endpoint URL in the Webhook URL field (e.g.
https://usebasin.com/f/YOUR_FORM_ID).
Step 3: Find your Form API Key
In your Basin dashboard, go to Form → Integrations → Form API Key and copy the key.
Step 4: Add the authentication and IP headers
In the CF7 Webhooks header configuration, add the following (CF7 Webhooks uses [tag_name] variables for dynamic values):
Basin-API-Key: YOUR_FORM_API_KEY
Basin-True-Client-IP: [_remote_ip]
Origin: [_url]
Referer: [_url]
User-Agent: [_user_agent]
| CF7 Variable | Description |
|---|---|
[_remote_ip] |
The IP address of the user who submitted the form |
[_url] |
The URL of the page containing the form |
[_user_agent] |
The user's browser user agent string |
That's it!
Once configured, CF7 will forward submissions to Basin with the user's real context. Basin will store the submission, apply spam filtering against the real IP, and trigger any configured notifications or webhooks.
Gravity Forms (Webhooks add-on)
Gravity Forms has a Webhooks add-on that can forward submissions to Basin.
Setup steps
- In WordPress, go to Forms → [Your Form] → Settings → Webhooks.
- Click Add New and set the Request URL to your Basin form endpoint.
- Set the Request Method to
POSTand the Request Format toForm. - Under Request Headers, add:
Basin-API-Key: YOUR_FORM_API_KEY
Basin-True-Client-IP: {ip}
Origin: {embed_url}
Referer: {referer}
User-Agent: {user_agent}
| Gravity Forms Merge Tag | Description |
|---|---|
{ip} |
The submitting user's IP address |
{embed_url} |
The URL of the page where the form is embedded |
{referer} |
The referring page URL ($_SERVER['HTTP_REFERER']) |
{user_agent} |
The user's browser user agent string |
Custom Server-Side Proxy
If you're building your own server-side form handler that forwards submissions to Basin, include the headers using the values from the original HTTP request:
=== "Ruby"
```ruby
require 'net/http'
require 'uri'
def forward_to_basin(params, original_request)
uri = URI('https://usebasin.com/f/YOUR_FORM_ID')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['Basin-API-Key'] = ENV['BASIN_FORM_API_KEY']
request['Basin-True-Client-IP'] = original_request.remote_ip
request['Origin'] = original_request.origin
request['Referer'] = original_request.referer
request['User-Agent'] = original_request.user_agent
request.set_form_data(params)
http.request(request)
end
```
=== "Node.js"
```javascript
const fetch = require('node-fetch');
const FormData = require('form-data');
async function forwardToBasin(params, originalReq) {
const form = new FormData();
Object.entries(params).forEach(([key, value]) => form.append(key, value));
await fetch('https://usebasin.com/f/YOUR_FORM_ID', {
method: 'POST',
headers: {
'Basin-API-Key': process.env.BASIN_FORM_API_KEY,
'Basin-True-Client-IP': originalReq.ip,
'Origin': originalReq.headers.origin,
'Referer': originalReq.headers.referer,
'User-Agent': originalReq.headers['user-agent'],
},
body: form,
});
}
```
=== "PHP"
```php
function forwardToBasin(array $params): void {
$data = http_build_query($params);
$context = stream_context_create([
'http' => [
'method' => 'POST',
'header' => implode("\r\n", [
'Basin-API-Key: ' . $_ENV['BASIN_FORM_API_KEY'],
'Basin-True-Client-IP: ' . $_SERVER['REMOTE_ADDR'],
'Origin: ' . $_SERVER['HTTP_ORIGIN'] ?? '',
'Referer: ' . $_SERVER['HTTP_REFERER'] ?? '',
'User-Agent: ' . $_SERVER['HTTP_USER_AGENT'] ?? '',
'Content-Type: application/x-www-form-urlencoded',
]),
'content' => $data,
],
]);
file_get_contents('https://usebasin.com/f/YOUR_FORM_ID', false, $context);
}
```
Why This Matters for Spam Protection
Basin's spam filters rely heavily on the submitting IP address. When submissions arrive directly from a user's browser, Basin automatically captures the correct IP. When submissions are forwarded by a server, Basin would otherwise see the server's IP — which is shared by many users and often not a reliable spam signal.
By passing Basin-True-Client-IP along with a valid Basin-API-Key, you're telling Basin:
"This request was forwarded by a trusted intermediary. The real submitter was at this IP address."
Basin then applies all its normal spam checks — including IP reputation and content analysis — against the original user's IP, keeping your form protected even when submissions flow through a third-party tool.
Shared hosting IPs
This is especially important if your WordPress site (or any server-side forwarder) is on shared hosting. Without the Basin-True-Client-IP header, Basin would see a shared hosting IP that may already be flagged as a spam source, causing legitimate submissions to be incorrectly rejected.
Security Considerations
- Never expose your API key in client-side code. These headers should only be added by your server or plugin — never in browser-side JavaScript.
- Use the Form API Key, not the Account API Key, to limit the scope of access.
- Rotate keys if compromised. You can regenerate your Form API Key from the Integrations page in your Basin dashboard.
Related
- WordPress Integration - Full guide for integrating Basin with WordPress, including Contact Form 7
- Authentication & Tokens - Learn about Basin's API key types
- Webhooks (Outbound) - Configure Basin to forward submissions to other services
- Spam Protection Overview - How Basin's spam filters work