# Introduction (/docs) Layer3 Intel provides the world's leading residential proxy detection platform. Start blocking anonymized threats on your website within minutes using our suite of proxy detection solutions. ## Our Services [#our-services] # Intel API Overview (/docs/intel-api/overview) The Intel API lets you check any IP address against the world's most complete database of residential proxy networks. 10,000 free requests are automatically granted upon registration to allow for testing. ## Usage [#usage] Querying the API is a simple GET request with the IP and your API key supplied as parameters. You can obtain your API key from the [dashboard](https://layer3intel.com/dashboard) ```bash $ curl "https://api.layer3intel.com/lookup?ip=1.1.1.1&key=YOUR_KEY_HERE" { "last_seen": 1779107932, "networks": ["IPROYAL", "BRIGHTDATA"], "percent_days_seen": 16, "proxy": true, "score": 0.47, "type": "residential" } ``` ## Field Descriptions [#field-descriptions] | Field | Type | Description | | ------------------- | --------- | -------------------------------------------------------------------------------------------------------------------- | | `last_seen` | integer | Unix timestamp (seconds) of the most recent time the IP was observed in proxy network traffic. | | `networks` | string\[] | Proxy networks the IP has been observed operating in. | | `percent_days_seen` | integer | Percentage of days the IP has been observed active in proxy networks over the last 30 days. | | `proxy` | boolean | Indicates whether the IP is associated with proxy networks. | | `score` | float | A 0-1 value indicating the activity level of a residential proxy. Only present when `type` is equal to `residential` | | `type` | enum | `residential` or `ISP` | ## Proxy Threat Score Guide [#proxy-threat-score-guide] | Score Range | Risk Level | Description | | ----------- | --------------------------------------- | ----------------------------------------------------------- | | = 1 | High volume proxy | actively sending requests through residential proxy network | | > 0.9 | Active residential proxy | high confidence detection | | > 0.7 | Recently associated with proxy networks | recommended to block | | > 0.5 | Low volume proxy | periodically inactive | | 0.05 - 0.5 | Contextual blocking | depends on use case and false positive threshold | | \< 0.05 | Low risk | not associated with proxy networks recently | # Assessment Object (/docs/tripwire/assessment-object) The decrypted tripwire assessment object returns fields that describe the users connection. ```javascript { proxy: true, proxy_type: 'residential', timestamp: 1759947137, source_ip: '1.1.1.1', key: '8ZPjAtv9QHpjRqVS', uuid: 'e4e97a46-fb24-4192-a74a-5ebb0ca0c303' } ``` ## Field Descriptions [#field-descriptions] | Field | Type | Description | | ------------ | ------- | --------------------------------------------------------------------------------- | | `proxy` | boolean | Indicates whether the user's connection is detected as coming from a proxy server | | `proxy_type` | enum | `residential` or `ISP` | | `timestamp` | number | Unix timestamp indicating when the assessment was performed. | | `source_ip` | string | The IP address from which the request originated | | `key` | string | The public key associated with this assessment | | `uuid` | string | A universally unique identifier for the specific assessment request | ## Assessment Verification [#assessment-verification] Due to the stateless nature of encrypted assessment tokens certain validations should be implemented to ensure the integrity and authenticity of assessment submissions, implement the following verification checks: ### Source IP Verification [#source-ip-verification] Validate that the `source_ip` in the assessment object matches the actual IP address of the incoming request. This prevents attackers from submitting assessments generated from different IP addresses. ### Timestamp Validation [#timestamp-validation] Verify that the assessment was generated recently by checking the `timestamp` field. This prevents the use of old assessments and ensures submissions are from recent evaluations. ### UUID Replay Attack Prevention [#uuid-replay-attack-prevention] Track used UUIDs to prevent replay attacks where the same assessment is submitted multiple times. # Bandwidth Drain (/docs/tripwire/bandwidth-drain) Residential proxy providers typically charge by the gigabyte. Bandwidth drain takes advantage of that pricing model by sending up to **10MB** through a confirmed residential proxy connection. The proxy provider meters the transfer and bills the scraper using it. At scale, the cost adds up quickly: 1,000 completed drains transfer about **10GB** through the scraper's proxy network. Rotating IP addresses does not avoid the cost because each confirmed residential exit can be drained. This makes repeated scraping more expensive and, at sufficient volume, uneconomical. Normal visitors do not receive the payload. Datacenter and ISP proxies are also excluded because bandwidth is generally cheaper for those services, so a drain would not create the same economic pressure. ## Enable bandwidth drain [#enable-bandwidth-drain] Bandwidth drain is off by default. Enable it with the `bandwidthDrain` option. ### Script URL parameter [#script-url-parameter] ```html ``` ### Data attribute [#data-attribute] ```html ``` ### At runtime [#at-runtime] ```javascript window.Tripwire.init({ bandwidthDrain: true }); const result = await window.Tripwire.run({ bandwidthDrain: true }); ``` `run(options)` applies its options through `init()`, so the setting remains active for later runs on the same page. Pass `{ bandwidthDrain: false }` to disable it again. ## Eligible connections [#eligible-connections] A drain runs only when all three conditions are met: 1. `bandwidthDrain` is enabled. 2. The RTT probe detects the additional hop created by a forwarded connection. 3. Layer3 identifies the IP address as a known residential proxy exit. If any check fails, Tripwire skips the drain. This includes normal connections, datacenter and ISP proxies, unlisted proxy exits, and connections where the RTT result and IP classification do not agree. If the client disconnects before receiving the full 10MB, only the bytes already transferred count toward its bandwidth usage. ## Trade-offs [#trade-offs] A drain delays the assessment token until the transfer finishes or reaches its 60-second limit. When bandwidth drain is enabled, Tripwire raises the effective timeout floor to 70 seconds, even if `timeout` is set lower. Connections that do not qualify for a drain follow the normal path without this delay. Avoid enabling bandwidth drain on a blocking form submission. With `auto=form`, the form waits for the assessment token, which can leave a confirmed proxy connection waiting for several seconds. Use bandwidth drain on content pages, listings, and other routes you want to protect from scraping. If a drain cannot complete, `run()` rejects and the `tripwire:error` event fires. Handle that case in your integration if the surrounding flow depends on receiving a token. # Installing Tripwire (/docs/tripwire/overview) Tripwire is a lightweight, framework-agnostic JavaScript snippet that provides real-time proxy and bot detection for your website. Adding it to your website is as simple as adding a javascript snippet. Start detecting anonymized threats on your website within minutes following the instructions below. ## API Keys [#api-keys] Before implementing Tripwire, you'll need to obtain your API keys from the Layer3 Intel dashboard: * **Public Key**: Passed to the embedded snippet to activate Tripwire on your website * **Private Key**: Used for API based token decryption * **Decryption Key**: Used to decrypt the tripwire assessment directly on your server You can find your API keys at: [https://layer3intel.com/dashboard/tripwire](https://layer3intel.com/dashboard/tripwire) ## Quick Start [#quick-start] ### 1. Add the Script [#1-add-the-script] Add the Tripwire script to your website using a standard script tag. The script can be loaded with your preferred loading strategy: ```html ``` ### 2. Run Detection and Get Token [#2-run-detection-and-get-token] The simplest way to use Tripwire is to call the detection function and use the returned token in your form submissions: ```javascript const tripwireResult = await window.Tripwire.run(); ``` ### 3. Submit Token with Form [#3-submit-token-with-form] Pass the encrypted token to your backend for validation: ```javascript async function handleFormSubmit(formData) { const tripwireResult = await window.Tripwire.run(); const payload = { ...formData, tripwire_token: tripwireResult.token }; // Submit to your backend await fetch('/api/submit', { method: 'POST', body: JSON.stringify(payload), headers: { 'Content-Type': 'application/json' } }); } ``` ### 4. Decrypt Token on Backend [#4-decrypt-token-on-backend] After receiving a form submission with the tripwire token you can decrypt it using standard JWE libraries and the decryption key obtained from your dashboard: ```javascript import { importPKCS8, jwtDecrypt } from 'jose'; async function decrypt(encryptedPayload, privateKeyPEM) { const privateKey = await importPKCS8(privateKeyPEM, 'ECDH-ES'); const { payload } = await jwtDecrypt(encryptedPayload, privateKey); return payload; } const privateKeyPEM = `-----BEGIN PRIVATE KEY----- MIGaAgEAMBMGByqGSA49AgEGCCqGSM49AwEHBG0wawIKAQQgP8gsrfq+XU/QVRW2 OX7xT/TOd/rumKhgQmJ6d+psTHOhRANCJAQb+Q8u/FVhRfcjZ9oW342S5FjEm2nH +a8Hw+cvT+F0dR67yeA7r+QyA20fv029s0vtjTYJ69h7w6qFaCDVsG+J -----END PRIVATE KEY-----`; const encryptedPayload = `eyJhbGciOiJFQ0RpLUVTIiwiZW5jIjoiQTI1MkdDTSIsImVwayI6eyJjcnYiciJQLTI1NiIsImt0eSIKIkVDIiwieCI6IkExVUNDbHNqaWM2ZVZRNVVweHJ2Z282aUNRdWVOOEUnVzh0VlJRX2d4aTliLCJ5IjoiUDdhcWJIZmlFWEw0UVlYVXQ2SEpPWlpjaUY5STRFbmpKdWRaSUJzV1cyeSJ4fQ..HWfQajr6hKE8DRew.1lBUuf_6SrkWGbi5vHNozvlp2UHCXKfBhTb6s9ITt9mIj-HpM9mkeEdULh9Y4_GJ_jlNpgji1sngFnM3qwGabkm7cf23Fj3nGY3MBBKyfWqLffyptUmnaoZdemVJXCEcertzd9orBLc_xjXLAZOOEQ8-1ce1tKQX8c29pzYAKXTsYwd7zGrq_A.eYfdDJp8RiwcJdVmB1M26w`; const result = await decrypt(encryptedPayload, privateKeyPEM); ``` Alternatively, you can use the decryption API with the private API key from your dashboard: ```javascript const response = await fetch('https://tripwire.layer3intel.com/decrypt', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify({ key: privateToken, payload: req.body.payload, }), }); ``` ## Configuration Options [#configuration-options] The script accepts several URL parameters for configuration: * `key`: Your API key (required) * `auto`: Set to "true" for automatic detection on page load or "form" to run on form submissions * `field`: Hidden form field name for automatic token insertion (must be set to auto-inject on form submission) * `forms`: CSS selector for forms to monitor (default: "form\[data-tripwire]") * `timeout`: Milliseconds to wait for a result before failing (default: 8000) * `bandwidthDrain`: Set to "true" to enable [bandwidth drain](/docs/tripwire/bandwidth-drain), which deters scraping by billing confirmed residential proxy connections for the bandwidth they take. Never runs on real visitors (default: "false") Every option can also be supplied as a `data-` attribute on the script tag (`data-key`, `data-auto`, `data-bandwidth-drain`), or passed to `window.Tripwire.init()` at runtime. ## Usage Examples [#usage-examples] ### Manual Detection [#manual-detection] ```javascript // Run detection manually const result = await window.Tripwire.run(); if (result.status === 'success') { console.log('Detection completed in', result.elapsedMs, 'ms'); // Use result.token for validation } ``` ### Automatic Form Integration [#automatic-form-integration] ```html
``` ### Event Handling [#event-handling] ```javascript // Listen for detection events window.Tripwire.on('tripwire:success', (event) => { console.log('Detection successful:', event.detail); }); window.Tripwire.on('tripwire:error', (event) => { console.log('Detection failed:', event.detail.error); }); ```