Skip to content

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

  1. In WordPress, go to Contact → Contact Forms and open your form.
  2. Click the Webhook tab.
  3. 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

  1. In WordPress, go to Forms → [Your Form] → Settings → Webhooks.
  2. Click Add New and set the Request URL to your Basin form endpoint.
  3. Set the Request Method to POST and the Request Format to Form.
  4. 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.