# SERP API
Source: https://docs.joinmassive.com/advanced-features/serp-api
Extract live results from popular search engines
## Usage
The search service has a RESTful interface that accepts `GET` requests at
**https\://beta.api.joinmassive.com/search**.
Searches are performed in real time by default or can be queued for
[later retrieval](#asynchronous-mode). Real-time searches take an average of a few seconds but may
require multiple retries, in which case up to **120 seconds** is allocated per API request.
### Authentication
You can access the service by including
[your secret API token](https://partners.joinmassive.com/profile) in an `Authorization` header:
```http
Authorization: Bearer [Insert API token here]
```
Here’s an example request that uses the [common Curl command](https://curl.se/):
```bash
$ curl -H "Authorization: Bearer $MASSIVE_API_TOKEN" \
'https://beta.api.joinmassive.com/search?terms=foo'
```
### Search parameters
Required and optional parameters can be added in a
[standard query string](https://developer.mozilla.org/en-US/docs/Learn/Common_questions/What_is_a_URL#parameters).
The keys and values that Massive supports are as follows:
| Key | Required | Value |
| :------------ | :------- | :---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `terms` | ✅ | The broad or exact word or phrase to query (e.g., `foo bar baz` or `"foo bar baz"`); the terms require [form or URL encoding](https://developer.mozilla.org/en-US/docs/Glossary/Percent-encoding) (with any space character being replaced by a `+` character or `%20` sequence) |
| `serps` | ⬜ | The number of results pages to retrieve, from `1` to `10` inclusive; `1` is the default count |
| `size` | ⬜ | **\[Google only]** The number of results per page to retrieve, from `0` to `100` inclusive; page size is unset by default |
| `offset` | ⬜ | **\[Google only]** The number of initial results to skip, from `0` to `100` inclusive; results aren’t offset by default |
| `engine` | ⬜ | The search engine to use, `google`, `bing`, or `duckduckgo`; `google` is the default engine |
| `device` | ⬜ | **\[Google only]** The name as returned by the [devices endpoint](#device-emulation) of the device to emulate searching on (these names are case insensitive but must include form- or URL-encoded spaces and punctuation marks); searching is done on a desktop browser by default |
| `country` | ⬜ | The [two-letter ISO code](https://www.iso.org/obp/ui/#search) of the country to search from (these codes are case insensitive); a random country will be used by default |
| `subdivision` | ⬜ | The alphanumeric second part (proceeding the separator) of a [first-level subdivision code](https://www.iso.org/obp/ui/#search) in the (prerequisite) country to search from (these codes are case insensitive); a random subdivision will be used by default |
| `city` | ⬜ | The [commonly spelled name](https://www.geonames.org/) of the city in the (prerequisite) country to search from (these names are temporarily case sensitive and required to include form- or URL-encoded spaces and punctuation marks); a random city will be used by default |
| `uule` | ⬜ | **\[Google only]** The [proprietary encoded string](https://moz.com/blog/geolocation-the-ultimate-tip-to-emulate-local-search) for emulating the location to search from; if possible, the actual location will be searched from not emulated; location emulation is unused by default |
| `language` | ⬜ | **\[Google only]** The commonly spelled name, [two-letter ISO code](https://www.loc.gov/standards/iso639-2/php/code_list.php), or [Google code](https://www.google.com/advanced_search) of the language to search in (these names and codes are case insensitive but required to include form- or URL-encoded spaces and punctuation marks); the language is unset by default |
| `mode` | ⬜ | The synchronous or asynchronous timing of when to retrieve results, `sync` or `async` (see [details below](#asynchronous-mode)); `sync` is the default mode |
| `format` | ⬜ | The format to output to, `html` or `json` (see [details below](#response-format)); `html` is the default format |
| `expiration` | ⬜ | The maximum age of cached results in days to accept, where `0` will disable caching; `1` is the default number of days |
| `subaccount` | ⬜ | Any unique identifier of up to 255 characters (regardless of character encoding); Massive will bill requests made from subaccounts separately |
### Device emulation
The `device` parameter (which is currently limited to Google searches) lets you fetch
device-specific results, rather than the default desktop results. For a list of supported smartphone
and tablet devices, make a request with your API token and no parameters to
**https\://beta.api.joinmassive.com/search/devices**:
```bash
$ curl -H "Authorization: Bearer $MASSIVE_API_TOKEN" \
'https://beta.api.joinmassive.com/search/devices'
```
The API will return JSON that contains an alphabetized array of device names:
```json
[
"BlackBerry Z30",
"BlackBerry Z30 landscape",
"Galaxy Note 3",
"[Remaining device names here]"
]
```
### Asynchronous mode
A search request that includes the `mode=async` key-value pair will be satisfied asynchronously:
```bash
$ curl -H "Authorization: Bearer $MASSIVE_API_TOKEN" \
'https://beta.api.joinmassive.com/search?terms=foo&mode=async'
```
In response, the API will provide a JSON job identifier:
```json
{ "id": "078fd246-f0f7-44a0-aabb-cadd7b12454f" }
```
The job results or status can be requested at any time thereafter by passing a token and the
identifier to **https\://beta.api.joinmassive.com/search/results**:
```bash
$ curl -H "Authorization: Bearer $MASSIVE_API_TOKEN" \
'https://beta.api.joinmassive.com/search/results?id=078fd246-f0f7-44a0-aabb-cadd7b12454f'
```
The results, if ready, will be returned in the
[same format as synchronous results](#response-format); otherwise, a JSON status message will be
returned.
A `retrieving` status indicates that the search is in progress:
```json
{ "status": "retrieving" }
```
A `failed` status indicates that the search was unsuccessful and the request should be retried:
```json
{ "status": "failed" }
```
### Response format
You can receive search results in their original HTML or as structured JSON.
#### HTML
Google and Bing don’t feature infinite scrolling, so if you request more than one results page from
those search engines, the HTML of each page will be separated from the next by an empty line
(`\n\n`).
#### JSON
If you set the output to JSON, your results will be parsed into nested objects as in the following
example:
```json
{
"query": "foo",
"approxResultsCount": 255000000,
"resultsCount": 43,
"results": [{
"type": "organic",
"page": 1,
"section": "main",
"feature": 1,
"position": 1,
"url": "https://foofighters.com/",
"title": "Foo Fighters",
"site": "Foo Fighters",
"visibleUrl": "https://foofighters.com",
"date": null,
"snippet": "Official website of Foo Fighters.",
"rating": null,
"votes": null,
"sitelinks": [{
"position": 1,
"url": "https://foofighters.com/tour-dates/",
"title": "Tour Dates"
}, {
"position": 2,
"url": "https://shop.foofighters.com/",
"title": "Shop"
}, {
"position": 3,
"url": "https://foofighters.com/news/",
"title": "News"
}, {
"position": 4,
"url": "https://foofighters.com/news/a-message-from-the-hawkins-family/",
"title": "A Message from The Hawkins..."
}],
"images": []
}, {
"type": "also-asked",
"page": 1,
"section": "main",
"feature": 2,
"position": 1,
"question": "What does foo mean?",
"answer": {
"heading": null,
"description": "Foo (pronounced FOO) is a term used by programmers as a placeholder for a value that can change, depending on conditions or on information passed to the program.",
"date": null,
"url": "https://www.techtarget.com/searchapparchitecture/definition/foo-in-software-programming#:~:text=Foo%20(pronounced%20FOO)%20is%20a,information%20passed%20to%20the%20program.",
"title": "What Is Foo in Software Programming? Definition from ...",
"site": "TechTarget",
"visibleUrl": "https://www.techtarget.com › searchapparchitecture › foo-..."
}
}, {
"type": "also-asked",
"page": 1,
"section": "main",
"feature": 2,
"position": 2,
"question": "What is the English word Foo?",
"answer": {
"heading": null,
"description": "noun (1) ˈfü(ˌ)fü plural -s. slang. : fool, ninny.",
"date": null,
"url": "https://www.merriam-webster.com/dictionary/foo-foo#:~:text=1%20of%202-,noun%20(1),%3A%20fool%2C%20ninny",
"title": "Foo-foo Definition & Meaning - Merriam-Webster",
"site": "Merriam-Webster",
"visibleUrl": "https://www.merriam-webster.com › dictionary › foo-foo"
}
}, {
"type": "also-asked",
"page": 1,
"section": "main",
"feature": 2,
"position": 3,
"question": "Why do Hispanics say \"foo\"?",
"answer": {
"heading": null,
"description": "Foo is the diminutive of “fool” (because that extra “L” makes it far too lengthy). It is a term of endearment and part of the common Southern California Latino vernacular. The use of “fool” is foreign to others. It can be taken as a challenge, especially if the wrong tone or cadence are used.",
"date": "Apr 11, 2022",
"url": "https://ouresquina.com/2022/a-head-nod-to-the-foos-friendly-or-not/#:~:text=Foo%20is%20the%20diminutive%20of,tone%20or%20cadence%20are%20used.",
"title": "A head nod to the Foos, friendly or not - Our Esquina",
"site": "Our Esquina",
"visibleUrl": "https://ouresquina.com › a-head-nod-to-the-foos-friendly-..."
}
}, {
"[Remaining “People also ask” results here]"
}, {
"type": "organic",
"page": 1,
"section": "main",
"feature": 3,
"position": 1,
"url": "https://en.wikipedia.org/wiki/Foo_Fighters",
"title": "Foo Fighters",
"site": "Wikipedia",
"visibleUrl": "https://en.wikipedia.org › wiki › Foo_Fighters",
"date": null,
"snippet": "Foo Fighters is an American rock band formed in Seattle in 1994. Founded as a one-man project by former Nirvana drummer Dave Grohl, the lineup now consists ...",
"rating": null,
"votes": null,
"sitelinks": [],
"images": [{
"position": 1,
"source": "[Image data here]",
"alt": "foo from en.wikipedia.org"
}]
}, {
"type": "organic",
"page": 1,
"section": "main",
"feature": 3,
"position": 2,
"url": "https://www.merriam-webster.com/dictionary/foo",
"title": "Foo Definition & Meaning",
"site": "Merriam-Webster",
"visibleUrl": "https://www.merriam-webster.com › dictionary › foo",
"date": null,
"snippet": "The meaning of FOO is Scottish variant of how.",
"rating": null,
"votes": null,
"sitelinks": [],
"images": [{
"position": 1,
"source": "[Image data here]",
"alt": "foo from www.merriam-webster.com"
}]
}, {
"type": "top-story",
"page": 1,
"section": "main",
"feature": 4,
"position": 1,
"url": "https://nypost.com/2024/09/10/entertainment/foo-fighters-dave-grohl-reveals-he-cheated-welcomed-baby-outside-of-marriage/",
"publisher": "New York Post",
"headline": "Foo Fighters’ Dave Grohl reveals he cheated on his wife, welcomed baby ‘outside’ of his marriage",
"date": "2 hours ago",
"image": "[Image data here]",
}, {
"type": "top-story",
"page": 1,
"section": "main",
"feature": 4,
"position": 2,
"url": "https://www.mirror.co.uk/3am/celebrity-news/breaking-dave-grohl-admits-cheating-33640293",
"publisher": "The Mirror",
"headline": "Foo Fighters' Dave Grohl admits cheating on wife as he reveals fathering secret baby",
"date": "3 hours ago",
"image": "[Image data here]",
}, {
"type": "top-story",
"page": 1,
"section": "main",
"feature": 4,
"position": 3,
"url": "https://www.nbcnews.com/news/us-news/dave-grohl-announces-become-father-baby-born-marriage-rcna170498",
"publisher": "NBC News",
"headline": "Dave Grohl announces he's become the father of a baby born outside his marriage",
"date": "1 hour ago",
"image": "[Image data here]",
}, {
"[Remaining “Top stories” results here]"
}, {
"[Remaining organic results here]"
}, {
"type": "also-searched",
"page": 1,
"section": "bottom",
"feature": 1,
"position": 1,
"url": "https://www.google.com/search?sca_esv=7f94d02cc2bb7a85&sca_upv=1&q=Dave+Grohl&stick=H4sIAAAAAAAAAOMwVGI0-MXIsIGF4RULFxeHfq6-gZGFafIrFm4uThDHMKUiLRkulWRYVQXnpJQVFsI5llm5FnCOWW6WCZxjbpyOUGZSlFyEMNvIoKgKzksxtDTOWMTK5ZJYlqrgXpSfkXOLTZKh-2mPcWB8SME7leaDUof2LHlq8nPd7DLvVYs4xAJS8wtyUhUSc4rzFYpTE4uSMxTS8osAI_QNztIAAAA&sa=X&ved=2ahUKEwi1vO_B_5yIAxV8ElkFHRySAR4Qs9oBKAB6BAhkEAk",
"query": "Dave Grohl"
}, {
"type": "also-searched",
"page": 1,
"section": "bottom",
"feature": 1,
"position": 2,
"url": "https://www.google.com/search?sca_esv=7f94d02cc2bb7a85&sca_upv=1&q=Taylor+Hawkins&stick=H4sIAAAAAAAAAOMwVGI0_MXIsIGF4RULFxeHfq6-gZGFafIrFm4uThDHMKUiLRkulWRYVQXnpJQVFsI5llm5FnCOWW6WCZxjbpyOUGZSlFyEMNvIoKgKzksxtDTOWMTKF5JYmZNfpOCRWJ6dmVd8i02Softpj3FgfEjBO5Xmg1KH9ix5avJz3ewy71WLOMQCUvMLclIVEnOK8xWKUxOLkjMU0vKLAL7S69nWAAAA&sa=X&ved=2ahUKEwi1vO_B_5yIAxV8ElkFHRySAR4Qs9oBKAB6BAhkEA4",
"query": "Taylor Hawkins"
}, {
"type": "also-searched",
"page": 1,
"section": "bottom",
"feature": 1,
"position": 3,
"url": "https://www.google.com/search?sca_esv=7f94d02cc2bb7a85&sca_upv=1&q=Nirvana+(band)&stick=H4sIAAAAAAAAAOMwVGI0-sXIsIGF4RULFxeHfq6-gZGFafIrFm4uThDHMKUiLRkulWRYVQXnpJQVFsI5llm5FnCOWW6WCZxjbpyOUGZSlFyEMNvIoKgKzksxtDTOWMTK55dZVJaYl6igkZSYl6J5i02Softpj3FgfEjBO5Xmg1KH9ix5avJz3ewy71WLOMQCUvMLclIVEnOK8xWKUxOLkjMU0vKLAJ7k8YDWAAAA&sa=X&ved=2ahUKEwi1vO_B_5yIAxV8ElkFHRySAR4Qs9oBKAB6BAhkEBM",
"query": "Nirvana"
}, {
"[Remaining “People also search for” results here]"
}]
}
```
## Additional examples
```bash
$ curl -H "Authorization: Bearer $MASSIVE_API_TOKEN" \
'https://beta.api.joinmassive.com/search?terms=foo+bar+baz&serps=2&engine=bing'
```
```bash
$ curl -H "Authorization: Bearer $MASSIVE_API_TOKEN" \
'https://beta.api.joinmassive.com/search?terms=%22foo+bar+baz%22&serps=10&engine=duckduckgo&country=us&format=json'
```
# Authentication
Source: https://docs.joinmassive.com/isp-proxies/authentication
We support HTTP, HTTPS, and SOCKS5
**Attention:** Make sure to carefully check that your credentials and port number are correct for your auth type.
## HTTP
How to authenticate using HTTP.
| | |
| --------- | ---- |
| HTTP Port | 8000 |
```bash
curl --proxy http://isp.joinmassive.com:8000 -U '{PROXY_USERNAME}:{API_KEY}' https://cloudflare.com/cdn-cgi/trace
```
## HTTPS
How to authenticate using HTTPS.
| | |
| ---------- | ---- |
| HTTPS Port | 4080 |
```bash
curl --proxy https://isp.joinmassive.com:4080 -U '{PROXY_USERNAME}:{API_KEY}' https://cloudflare.com/cdn-cgi/trace
```
## SOCKS5
How to authenticate using SOCKS5.
| | |
| ----------- | ---- |
| SOCKS5 Port | 8000 |
```bash
curl -x socks5h://isp.joinmassive.com:8000 -U '{PROXY_USERNAME}:{API_KEY}' https://www.cloudflare.com/cdn-cgi/trace
```
# Error Types
Source: https://docs.joinmassive.com/isp-proxies/error-types
Massive may respond with one of several common or custom error messages:
| Status code | Reason phrase | Additional comments |
| ----------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400` | Bad Request | Your request was malformed, most likely because of invalid routing parameters; see the response body for human-readable details |
| `407` | Proxy Authentication Required | Your login email address, Massive API token, or both were incorrect |
| `452` | Disallowed Content | The protocol, port, or content that you requested conflicts with Massive’s content policy; see the Link header for the entire policy |
| `500` | Internal server error | Something went wrong on the serverside |
| `502` | Bad gateway | Massive was unable to find an appropriate node |
| `503` | Service Unavailable | Massive was unable to satisfy the geotargeting specifications or other elements of your request; or Massive network experiences high demand; see the response body for human-readable details |
# Geotargeting
Source: https://docs.joinmassive.com/isp-proxies/geotargeting
You can tune the request by providing geo parameters like an [ISO ZIP code, subdivision, and country code](https://www.iso.org/obp/ui/#search), and by [city](https://www.geonames.org/).
We do not support geo-targeting for ISP proxies yet.
# Introduction
Source: https://docs.joinmassive.com/isp-proxies/introduction
Massive ISP proxy networks use AT&T infrastructure to provide high-speed, rotating proxies across the US. With 10 Gbps speeds and automatic rotation capabilities, our proxies are perfect for your data collection needs.
**Key Features:**
* High-speed connectivity (10 Gbps)
* Automatic IP rotation
* Sticky session support
* Multiple protocol support (HTTP, HTTPS, and SOCKS5)
* US coverage
## Getting started
The first step to using Massive Network is making sure your credentials work with a simple curl request.
# .NET (in C#)
Source: https://docs.joinmassive.com/isp-proxies/samples/.net
.NET integrations should connect to the [Massive Network’s HTTP port](/isp-proxies/authentication#HTTP) `4080` because [.NET doesn’t broadly support HTTPS proxies yet](https://github.com/dotnet/runtime/pull/87638):
```csharp
using System.Net;
class Demo {
static async Task Main(string[] args) {
string username = Uri.EscapeDataString("{PROXY_USERNAME}");
string password = "{API_Key}";
string url = "https://cloudflare.com/cdn-cgi/trace"; // Insert your target URL here
string proxy = "http://isp.joinmassive.com:4080";
HttpClientHandler handler = new() {
Proxy = new WebProxy(proxy),
DefaultProxyCredentials = new NetworkCredential(
username, password
)
};
HttpClient client = new(handler);
HttpResponseMessage response = await client.GetAsync(url);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}
```
# Puppeteer
Source: https://docs.joinmassive.com/isp-proxies/samples/puppeteer
Integrate the Massive Network into your Puppeteer workflows by setting the `--proxy-server` launch flag then calling a page object’s `authenticate` method:
```javascript
#!/usr/bin/env node
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
args: ['--proxy-server=https://isp.joinmassive.com:4080']
});
const page = (await browser.pages())[0];
await page.authenticate({
username: '{PROXY_USERNAME},
password: '{API_KEY}'
});
await page.goto('https://cloudflare.com/cdn-cgi/trace'); // Insert your target URL here
console.log(await page.content());
browser.close();
})();
```
# (Vanilla) Python
Source: https://docs.joinmassive.com/isp-proxies/samples/python
To connect to the Massive Network from Python, include your encoded credentials in the proxy address (this usage doesn’t risk leaking your API token to a shared history file per the caveat for Curl):
```javascript
#!/usr/bin/env python3
import requests
import urllib
username = '{PROXY_USERNAME}'
password = '{API_KEY}'
url = 'https://cloudflare.com/cdn-cgi/trace' # Insert your target URL here
host = 'isp.joinmassive.com'
port = 4080
proxy = f'https://{username}:{password}@{host}:{port}'
response = requests.get(url, proxies={'http': proxy, 'https': proxy})
print(response.content)
```
# Ruby
Source: https://docs.joinmassive.com/isp-proxies/samples/ruby
Ruby’s standard HTTP library doesn’t seem to support HTTPS proxy connections, so connect to the [Massive Network’s HTTP port](/isp-proxies/authentication#http) with Ruby:
```javascript
#!/usr/bin/env node
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
args: ['--proxy-server=https://isp.joinmassive.com:4080']
});
const page = (await browser.pages())[0];
await page.authenticate({
username: '{PROXY_USERNAME},
password: '{API_KEY}'
});
await page.goto('https://cloudflare.com/cdn-cgi/trace'); // Insert your target URL here
console.log(await page.content());
browser.close();
})();
```
# Scrapy (for Python)
Source: https://docs.joinmassive.com/isp-proxies/samples/scrapy
After installing Scrapy (`pip install scrapy`) and creating a project (`scrapy startproject [project name]`), you can connect to the Massive Network by saving code like that below to a file in the new `[project name]/[project name]/spiders` subdirectory then running `scrapy crawl demo` from the top-level `[project name]` directory (Scrapy doesn’t seem to support HTTPS proxy connections, but you can use the [network’s HTTP port](/isp-proxies/authentication#http)):
```python
import scrapy
import urllib
class Demo(scrapy.Spider):
name = 'demo'
def parse(self, response):
print(response.body)
def start_requests(self):
username = '{PROXY_USERNAME}'
password = '{API_KEY}'
url = 'https://cloudflare.com/cdn-cgi/trace' # Insert your target URL here
host = 'isp.joinmassive.com'
port = 4080
proxy = f'http://{username}:{password}@{host}:{port}'
yield scrapy.Request(url, callback=self.parse, meta={'proxy': proxy})
```
# Sticky sessions
Source: https://docs.joinmassive.com/isp-proxies/sticky-sessions
Our ISP proxies support sticky sessions, allowing persistent IP connections and session-based routing without expiration.
## Using Sticky Sessions:
| Key | Value | Duration | Examples |
| ------- | --------------------------------------------- | ------------- | ------------------ |
| session | Any unique identifier of up to 255 characters | No expiration | 0, abc, session123 |
Add a session identifier to keep your requests on the same IP address:
```bash
curl --proxy http://isp.joinmassive.com:8000 -U '{PROXY_USERNAME}-session-37:{API_KEY}' ip-api.com
```
When using sticky sessions:
1. The first request with a session ID linked to a specific IP address.
2. All subsequent requests with the same session ID will use that same IP address.
3. Sessions continue indefinitely unless the session identifier is changed.
4. Requests that do not have a session ID will automatically be assigned a new IP address.
# Usage restrictions
Source: https://docs.joinmassive.com/isp-proxies/usage-restrictions
Some limitations apply to HTTP and SOCKS5 endpoints for ISP proxies.
## General Restrictions
* **No UDP Support:** UDP communication is restricted by default. [Contact support](support@joinmassive.com) if you require access.
* **Limited Ports:** Only standard ports (80, 443) are available.
* Allowed: `http://example.com/`, `https://example.com/`
* Not Allowed: `http://example.com:8080`
* **Content Policy:** The ISP proxy network is designed for activities falling within the legal framework of all jurisdictions. Requests targeting high-risk, offensive, harmful, or illegal content may be blocked.
Requests blocked due to protocol, port, or content restrictions return a `452 Disallowed Content` error.
## Restricted Domains
We restrict access to content that is generally used to evade the law or site TOS policies. If you are getting blocked from accessing certain content that you have a legitimate reason to access, then [contact support](https://joinmassive.atlassian.net/servicedesk/customer/portal/2/group/2/create/13) to complete our KYC process to gain access.
## Port 25
`Port 25` is not opened on our ISP proxy network. Submit a request if this feature is necessary.
## Request access
[Contact support](https://joinmassive.atlassian.net/servicedesk/customer/portal/2/group/2/create/13) if you have questions about our policies or want to complete KYC to gain access to content that is restricted by default.
# How can I contact the sales team?
Source: https://docs.joinmassive.com/kb/billing/how-can-i-contact-the-sales-team
For inquiries about pricing, free trials, and custom solutions:
1. Visit our [Free trial form](https://www.joinmassive.com/free-trial)
2. Submit your details
3. Our sales team will reach out to you promptly
# How to Access Your Bill.com Invoice
Source: https://docs.joinmassive.com/kb/billing/how-to-access-your-billcom-invoice
Welcome to partnering with Massive! We use [Bill.com](http://Bill.com) to issue our invoices, here's a quick guide on how to access and pay your invoices for the first time.
1. **Check Your Email:** You will get an invoice sent to the email on file with [Bill.com](http://Bill.com). This email will include a link to view and pay your invoice.
2. **Click the Link:** Click on the link in the email. This will take you to a secure page where you can view the invoice details.
3. **Create an Account (if needed):** If this is your first time using [Bill.com](http://Bill.com), you may need to create a free account. This is a simple process that requires your email address and a password.
4. **View Your Invoice:** Once you've logged into your account, you'll be able to see the invoice. You can download or print it for your records.
5. **Make a Payment:** If you're ready to pay, you can do so directly through [Bill.com](http://Bill.com) using various payment methods. You can also save a credit card on file that will automatically be charged on your due date.
**Need Help?**
If you have any trouble accessing your invoice or creating an account, please contact Jenn Starr at [support@joinmassive.com](mailto:support@joinmassive.com).
**Important Note:** This guide assumes you have received an email notification from us at Massive. If you haven't received an email, please check your spam folder or contact us directly.
# What are Massive Network's pricing and fees?
Source: https://docs.joinmassive.com/kb/billing/what-are-massive-networks-pricing-and-fees
Our pricing is usage-based with no setup fees or hidden costs. Volume discounts available for enterprise clients (contact [sales@joinmassive.com](mailto:sales@joinmassive.com)).
# What should I know about the free trial?
Source: https://docs.joinmassive.com/kb/billing/what-should-i-know-about-the-free-trial
We offer a 2 GB free trial:
* No credit card required
* Fill out [Free Trial form](https://www.joinmassive.com/free-trial)
* Partnership manager activates your trial
* Support available at [support@joinmassive.com](mailto:support@joinmassive.com)
# Are there any resources available for new users?
Source: https://docs.joinmassive.com/kb/faq/are-there-any-resources-available-for-new-users
Yes, Massive offers:
1. The [Quickstart Guide](https://docs.joinmassive.com/residential/quickstart) - A comprehensive guide with step-by-step instructions to help you get started with our proxy service
2. Our [Documentation Portal](https://docs.joinmassive.com/residential) - Access our full documentation where you can:
* Use the search bar to find specific information
* Browse through detailed tutorials
* Find answers to common questions
# How can I get technical support?
Source: https://docs.joinmassive.com/kb/faq/how-can-i-get-technical-support
We offer multiple support channels:
1. Support Portal: [Submit a ticket](https://forms.fillout.com/t/p8dRqBYs58us)
2. Email: [support@joinmassive.com](mailto:support@joinmassive.com)
# How can I request access to restricted content for legitimate business needs?
Source: https://docs.joinmassive.com/kb/faq/how-can-i-request-access-to-restricted-content-for-legitimate-business-needs
Follow these steps:
1. Submit a request through our [Massive Help Desk](https://forms.fillout.com/t/p8dRqBYs58us)
2. Complete the KYC (Know Your Customer) process
3. Provide documentation verifying your identity and business legitimacy
4. Await approval based on compliance with our policies
# How can users opt out of the service?
Source: https://docs.joinmassive.com/kb/faq/how-can-users-opt-out-of-the-service
Users can:
* Opt out at any time through application settings
* For Android/Fire OS with Foreground Service: Opt out via the notification interface
* Stop participation completely using the provided controls
# How do I create a Massive Network account?
Source: https://docs.joinmassive.com/kb/faq/how-do-i-create-a-massive-network-account
Creating an account with Massive Network is a straightforward process:
1. Visit our website at [http://www.joinmassive.com](http://www.joinmassive.com)
2. Click on the "Sign Up" button
3. Select your preferred plan
4. Fill out the required registration information
5. Submit your registration to complete the account creation process
# How do I find my proxy username and password?
Source: https://docs.joinmassive.com/kb/faq/how-do-i-find-my-proxy-username-and-password
To access your proxy credentials:
1. Sign in to your Massive account
2. Go to your Profile page at [http://partners.joinmassive.com/profile](http://partners.joinmassive.com/profile)
3. Your proxy username and password will be displayed directly on your dashboard
# How do I get started with Massive Network?
Source: https://docs.joinmassive.com/kb/faq/how-do-i-get-started-with-massive-network
Getting started with Massive Network involves four main steps:
1. Create Your Account
* Visit [joinmassive.com](http://www.joinmassive.com)
* Sign up and select your plan
* Complete the registration process
2. Access Your Credentials
* Log in to your account
* Go to [Profile](http://partners.joinmassive.com/profile)
* Locate your username and password
3. Configure Your Proxy
* Navigate to the Quickstart section at [Dashboard](http://partners.joinmassive.com/quickstart)
* Use the Massive Proxy Configurator
* Select your preferences:
* Location
* Protocol
* Other specific parameters
4. Establish Connection
* Generate your connection command using the configurator
* Run the generated command in your terminal
* Begin using your proxy connection
# What are subaccounts and how do they work?
Source: https://docs.joinmassive.com/kb/faq/what-are-subaccounts-and-how-do-they-work
Subaccounts in Massive Network are features that enable granular request management within your main account. They provide:
* Request isolation for separate entities
* Unique tracking with individual identifiers
* Independent usage and billing tracking
* Centralized management under the main account
Technical Requirements:
* Character Encoding: All encodings supported
* Maximum Length: 255 characters
* Uniqueness: Each identifier must be unique within your account
* **Format:** `{USERNAME}-subaccount-[IDENTIFIER]:{PASSWORD}`
# What reporting and analytics tools does Massive Network provide?
Source: https://docs.joinmassive.com/kb/faq/what-reporting-and-analytics-tools-does-massive-network-provide
Massive Network offers extensive reporting and analytics through our [Dashboard](https://partners.joinmassive.com/dashboard), organized into three main sections:
1. Overview Dashboard
* Plan status and bandwidth usage monitoring
* Current success rate metrics
* Interactive bandwidth trend graphs
* Real-time usage statistics
2. Detailed Analytics
* Request analysis by account, sub-account, and domain
* Key performance metrics:
* Total request count
* Successful request count
* Success rate percentages
* Bandwidth consumption
* Customizable filters for date, location, and domain
3. Account Statistics
* Current day performance metrics
* Historical data analysis
* Geographic connection distribution
* Success/failure rate breakdown by country
Additional Features:
* Interactive data visualization tools
* Customizable report filters
* Export data in multiple formats
* Detailed graph analysis for connection trends
Need Help? For assistance with analytics or custom reporting needs, contact our support team:
* Email: [support@joinmassive.com](mailto:support@joinmassive.com)
* [Support Portal](https://forms.fillout.com/t/p8dRqBYs58us)
# What types of proxies does Massive Network offer?
Source: https://docs.joinmassive.com/kb/faq/what-types-of-proxies-does-massive-network-offer
1. Residential IPs:
* Sourced from real residential devices
* Best for bypassing restrictions and appearing as genuine users
2. ISP Proxies:
* Static IPs assigned by internet service providers
* Features:
* High-speed connectivity (10 Gbps)
* AT\&T infrastructure across US
* Multiple protocol support (HTTP, HTTPS, SOCKS5)
* Automatic IP rotation
* Sticky session support
3. Datacenter IPs:
* High-performance proxies from datacenters
* Optimized for speed and reliability
4. Mobile Proxies:
* Routed through mobile networks
* Ideal for mobile user simulation and mobile-specific content
# Where can I find documentation and resources?
Source: https://docs.joinmassive.com/kb/faq/where-can-i-find-documentation-and-resources
You can access:
* [FAQ page](https://www.joinmassive.com/faq#Partners)
* [Easy to follow documentation](https://docs.joinmassive.com/)
# Where can I find my API token?
Source: https://docs.joinmassive.com/kb/faq/where-can-i-find-my-api-token
Log in to your Massive developer dashboard and navigate to the "Profile" section. The API token will be displayed there. If you can't find it, contact [support@joinmassive.com](mailto:support@joinmassive.com).
# How does Massive ensure compliance with GDPR and CCPA?
Source: https://docs.joinmassive.com/kb/general/how-does-massive-ensure-compliance-with-gdpr-and-ccpa
Massive is fully compliant with GDPR and CCPA. For detailed information, please refer to our [Privacy Policy One-Pager](https://drive.google.com/file/d/1eABA1M6QzD-2ClfcFbRcUAp3DX8aW8Yq/view?usp=sharing).
# What are the main use cases?
Source: https://docs.joinmassive.com/kb/general/what-are-the-main-use-cases
Our proxy network supports:
1. Network Intelligence:
* Real-time internet performance monitoring across 195+ countries
* Network security validation
* Global service availability tracking
2. Market Research:
* Competitive analysis
* Regional price comparisons
* SEO performance tracking
* Ad campaign verification
* Brand presence monitoring
3. Security Operations:
* Fraud prevention
* Malware tracking
* Machine learning model training
* Threat detection enhancement
# What content is restricted on the Massive Network?
Source: https://docs.joinmassive.com/kb/general/what-content-is-restricted-on-the-massive-network
The following content types are blocked:
* Malware or phishing websites
* Adult or explicit content
* Sites facilitating illegal activities
* Domains associated with evading laws or site Terms of Service (TOS)
# What is a Massive Network?
Source: https://docs.joinmassive.com/kb/general/what-is-a-massive-network
Massive Network is a global edge network built on a robust proxy infrastructure, characterized by the following features:
* **Network Size:** Over 1,000,000 verified residential devices.
* **Geographic Coverage:** Spanning 195+ countries.
* **Participation Model:** Devices voluntarily opt-in via the [Massive SDK](https://www.joinmassive.com/getpaid).
This infrastructure empowers businesses to access real-world user environments for tasks such as internet monitoring, market research, and security operations.
# What is ethical data collection and how does Massive ensure it?
Source: https://docs.joinmassive.com/kb/general/what-is-ethical-data-collection-and-how-does-massive-ensure-it
Ethical data collection means gathering data responsibly, respecting website terms of service, and using fair scraping practices like appropriate request rates. It also involves using proxies that are ethically sourced.
At Massive, we provide **100% ethically sourced residential proxies**. Every participant in our network gives explicit consent and opts in willingly. We ensure transparency by showing clear consent dialogs so everyone understands and agrees to the permissions they provide.
# What is Massive Network's infrastructure size?
Source: https://docs.joinmassive.com/kb/general/what-is-massive-networks-infrastructure-size
As of August 2025, our network consists of:
* Over 750,000 Daily Active Users
* 400,000+ concurrent IP addresses
* Unlimited concurrent connections supported
For detailed capacity planning, contact: [support@joinmassive.com](mailto:support@joinmassive.com)
# What is the IP distribution by country?
Source: https://docs.joinmassive.com/kb/general/what-is-the-ip-distribution-by-country
As of January 2025, sample Daily Active IPs (DAU):
* USA: 147,935
* GB: 65,120
* DE: 42,877
* BR: 29,615
* MX: 28,570
* FR: 25,998 (Additional countries available)
# Getting Started
Source: https://docs.joinmassive.com/kb/introduction
Welcome to the Massive Network Knowledge Base. Here you'll find answers to frequently asked questions, troubleshooting guides, and detailed information about our services.
## Quick Links
* **[Frequently Asked Questions](/kb/faq/how-can-i-get-technical-support)** - Common questions about our services
* **[Troubleshooting](/kb/troubleshooting/how-can-i-prevent-common-errors-before-they-occur)** - Fix common issues and errors
* **[Billing & Payments](/kb/billing/what-are-massive-networks-pricing-and-fees)** - Information about pricing and payments
* **[Technical Configuration](/kb/technical/what-ports-should-i-use-for-proxy-connections)** - Advanced setup and configuration
* **[SDK Integration](/kb/general/what-is-massive-networks-infrastructure-size)** - Developer resources and guides
## Need More Help?
If you can't find what you're looking for:
* Submit a support ticket: [Support Portal](https://forms.fillout.com/t/p8dRqBYs58us)
* Email us: [support@joinmassive.com](mailto:support@joinmassive.com)
* Contact sales: [Free Trial Form](https://www.joinmassive.com/free-trial)
# Does the SDK affect app performance or battery life?
Source: https://docs.joinmassive.com/kb/sdk/does-the-sdk-affect-app-performance-or-battery-life
No, the SDK is designed to operate with minimal impact by using only free/unused device resources.
### Android/Fire OS:
* Uses idle device resources and runs as a separate process to avoid interfering with the main application.
* When using Foreground Service, users are kept aware of resource usage through notifications
### iOS:
* Background processing only occurs when the device is charging to preserve battery life
* No special capabilities are required that might impact performance
### Windows:
* Runs as a separate process to avoid interfering with the main application.
* Users are notified of resource usage through the system tray notifications.
The SDK implements these battery and performance optimizations:
1. User control over participation
2. Option to use Background Service mode for less resource usage (Android/Fire OS)
3. Separate process architecture (Android/Fire OS/Windows)
4. Charging-only background processing (iOS)
For specific concerns about performance or battery usage, you can:
1. Contact support: [support@joinmassive.com](mailto:support@joinmassive.com)
2. Submit a ticket: [Support Portal](https://forms.fillout.com/t/p8dRqBYs58us)
Learn more about technical details:
* [Android Technical Details](https://docs.joinmassive.com/monetization-sdk/mobile-android#technical-details)
* [Windows Getting Started Guide](https://docs.joinmassive.com/monetization-sdk/desktop-windows#getting-started)
* [iOS Technical Details](https://docs.joinmassive.com/monetization-sdk/mobile-ios#technical-details)
# How can I check if a device is compatible with the SDK?
Source: https://docs.joinmassive.com/kb/sdk/how-can-i-check-if-a-device-is-compatible-with-the-sdk
Check against platform requirements:
* Android and Fire OS: SDK Level 21+ (Lollipop or later)
* Windows: [Check documentation](https://docs.joinmassive.com/monetization-sdk/desktop-windows) for specific requirements
* iOS: iOS 16.0 or later
The SDK will return appropriate error states if the device is incompatible.
# How can I monitor the SDK's network usage?
Source: https://docs.joinmassive.com/kb/sdk/how-can-i-monitor-the-sdks-network-usage
Each platform provides network usage tracking:
* **Android/Fire OS:** Use the `usage()` method in MassiveClient
* **Windows:** Use taskbar usage display functionality
* **iOS:** Use `MassiveClient.shared.getNetworkUsage()`
The usage is reported in bytes and can be monitored for resource management.
# How do I handle SDK updates?
Source: https://docs.joinmassive.com/kb/sdk/how-do-i-handle-sdk-updates
Update procedures vary by platform:
### Android/Fire OS:
* Update the dependency version in the Gradle configuration
* Follow the migration guide when upgrading from 0.x to 1.0
Learn more: [Migration Guide](https://docs.joinmassive.com/monetization-sdk/mobile-android#migration-from-version-0-x)
### Windows:
* The Massive service supports auto-updates distributed by Massive and will update automatically after installation.
* The client library does not update automatically—you must manually update the SDK package in your project.
Learn more: [Windows Guide](https://docs.joinmassive.com/monetization-sdk/desktop-windows#getting-started)
### iOS:
* Download the latest xcframework
* Update the embedded framework in Xcode
* Test integration after updates
Learn more: [iOS Integration Guide](https://docs.joinmassive.com/monetization-sdk/mobile-ios#integration-guide)
# How do I initialize the Massive SDK on Android/Fire OS?
Source: https://docs.joinmassive.com/kb/sdk/how-do-i-initialize-the-massive-sdk-on-androidfire-os
Use the following method in your `Activity` or `Application` class:
```java
MassiveClient.init(API_TOKEN, this)
```
Learn more: [Android Integration Guide](https://docs.joinmassive.com/monetization-sdk/mobile-android#integration-to-the-app).
# How do I initialize the Massive SDK on iOS?
Source: https://docs.joinmassive.com/kb/sdk/how-do-i-initialize-the-massive-sdk-on-ios
Use the following code:
```swift
MassiveClient.shared.initAsync(apiToken: {API_TOKEN}) { status in
switch status {
case .initialized:
// Handle successful initialization
case .error:
// Handle initialization error
}
}
```
Learn more: [iOS Integration Guide](https://docs.joinmassive.com/monetization-sdk/mobile-ios#integration-to-the-app).
# How does the Massive SDK work and make money for developers?
Source: https://docs.joinmassive.com/kb/sdk/how-does-the-massive-sdk-work-and-make-money-for-developers
The SDK generates revenue by using small amounts of users' idle device resources (with consent) to perform tasks such as processing public web data and running simulations. This provides an ad-free experience while monetizing your app.
# How does the SDK handle service interruptions?
Source: https://docs.joinmassive.com/kb/sdk/how-does-the-sdk-handle-service-interruptions
Each platform provides service recovery mechanisms:
### Android/Fire OS
* You can **optionally** set a callback when calling the `init` method
* This callback will receive the **initial service state** after initialization
* To check the service state later, the user must call the `state` method manually
### Windows
* You can set callbacks for service availability:
* `MassiveSetServiceUnavailableCallback` (when the service becomes unavailable)
* `MassiveSetServiceAvailableCallback` (when the service becomes available)
* You can also set callbacks to track service start/stop events triggered from the **service UI** instead of the app UI:
* `MassiveStartedViaTaskbarCallback` (when started from the service UI)
* `MassiveStoppedViaTaskbarCallback` (when stopped from the service UI)
### iOS
* You **must** set a callback when calling the `initAsync` method.
* This callback will receive the **initial service state** after initialization.
* To check the service state later, the user must call the `getStatus` method manually.
# How is revenue calculated using the Massive SDK?
Source: https://docs.joinmassive.com/kb/sdk/how-is-revenue-calculated-using-the-massive-sdk
For information about revenue calculation:
1. Contact support: [support@joinmassive.com](mailto:support@joinmassive.com)
2. Submit a ticket: [Support Portal](https://forms.fillout.com/t/p8dRqBYs58us)
# Using Massive Residential Proxies with Python (Requests)
Source: https://docs.joinmassive.com/kb/sdk/using-massive-residential-proxies-with-python-requests
### Step 1: Install Required Library
Ensure you have the `requests` library installed. Run:
```bash
pip install requests
```
### Step 2: Configure Proxy
Retrieve your Massive credentials (username and password) from the **Profile** section of the dashboard. Format your proxy URL as:
```
https://:@network.joinmassive.com:65535
```
### Step 3: Code Example
The following Python script demonstrates how to send requests through Massive Residential Proxies:
```python
import requests
# Construct the proxy URL
proxy_url = "https://:@network.joinmassive.com:65535"
# Set up proxies for requests
proxies = {
"http": proxy_url,
"https": proxy_url,
}
# Send a request through the proxy
try:
response = requests.get("https://httpbin.io/ip", proxies=proxies)
print(response.text)
except requests.exceptions.RequestException as e:
print(f"Error occurred: {e}")
```
# Using Residential Proxies with Selenium (Python)
Source: https://docs.joinmassive.com/kb/sdk/using-residential-proxies-with-selenium-python
To use proxies with Selenium in Python, it's recommended to use Selenium Wire ([https://pypi.org/project/selenium-wire/](https://pypi.org/project/selenium-wire/)) instead of standard Selenium. Selenium Wire supports proxies with username and password authentication, which standard Selenium does not.
Install the required packages by running:
```bash
pip install selenium selenium-wire webdriver-manager
```
Here's a Python example for integrating Massive proxies with Selenium Wire:
```python
from seleniumwire import webdriver
from selenium.webdriver.chrome.service import Service
from webdriver_manager.chrome import ChromeDriverManager
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
def configure_proxy(username, password, address, port):
proxy_url = f"http://{username}:{password}@{address}:{port}"
return {"proxy": {"http": proxy_url, "https": proxy_url}}
def initialize_driver(proxy_options):
chrome_options = Options()
chrome_options.add_argument("--headless") # Remove this line to see the browser
driver = webdriver.Chrome(
service=Service(ChromeDriverManager().install()),
seleniumwire_options=proxy_options,
options=chrome_options,
)
return driver
def test_connection(driver, test_url):
driver.get(test_url)
return driver.find_element(By.TAG_NAME, "body").text
if __name__ == "__main__":
PROXY_USERNAME = ""
PROXY_PASSWORD = ""
PROXY_ADDRESS = "network.joinmassive.com"
PROXY_PORT = "65534"
proxy_settings = configure_proxy(
PROXY_USERNAME, PROXY_PASSWORD, PROXY_ADDRESS, PROXY_PORT
)
driver = initialize_driver(proxy_settings)
try:
test_url = "https://httpbin.io/ip"
ip_response = test_connection(driver, test_url)
print(ip_response)
finally:
driver.quit()
```
If you encounter connection issues while using proxies with Selenium Wire, check the following:
1. **Proxy Credentials**: Ensure the username and password are correct.
2. **Proxy Host and Port**: Verify you're using the correct host (network.joinmassive.com) and port (65534).
3. **Proxy URL Format**: Confirm the proxy URL starts with http\://.
# What are the minimum requirements for Android/Fire OS integration?
Source: https://docs.joinmassive.com/kb/sdk/what-are-the-minimum-requirements-for-androidfire-os-integration
* Android SDK Level 21 (Lollipop) or later
* Kotlin version 1.9.0 or later
* Java version 17 or later
Learn more:
* [Android Requirements](https://docs.joinmassive.com/monetization-sdk/mobile-android#technical-requirements)
* [Fire OS Requirements](https://docs.joinmassive.com/monetization-sdk/tv-fire#technical-requirements)
# What are the minimum requirements for iOS integration?
Source: https://docs.joinmassive.com/kb/sdk/what-are-the-minimum-requirements-for-ios-integration
* iOS Minimum Deployment: 16.0
* iOS Deployment Target: 16.0 or later
* Swift version: 5.10 or later
* No special capabilities required
Learn more: [iOS Technical Requirements](https://docs.joinmassive.com/monetization-sdk/mobile-ios#technical-requirements)
# What are the service types available in Android/Fire OS?
Source: https://docs.joinmassive.com/kb/sdk/what-are-the-service-types-available-in-androidfire-os
The SDK offers two service types:
1. Foreground Service:
* More visible with customizable notification
* Higher earning potential
* Less likely to be killed by the system
* Requires notification configuration
2. Background Service:
* Runs silently
* Less intrusive
* No visible notification
* May be more likely to be terminated by the system
# What happens to the SDK when the app is suspended or terminated?
Source: https://docs.joinmassive.com/kb/sdk/what-happens-to-the-sdk-when-the-app-is-suspended-or-terminated
Behavior varies by platform:
* **Android/Fire OS:** The service can continue running as a separate process in Foreground or Background mode. However, the runtime is limited and depends on whether the device is connected to power.
* **Windows:** Can be configured to stop on app quit using `STOP_MASSIVE_ON_APP_QUIT` option
* **iOS:** State persists in the background but not across launches. If the app is configured to run in the background, it can wake up at regular intervals (approximately every 30 minutes) and run for up to 5 minutes, but only if the device is connected to power.
# What is the Massive SDK?
Source: https://docs.joinmassive.com/kb/sdk/what-is-the-massive-sdk
The Massive SDK is a monetization tool that allows developers to generate revenue from their apps without relying on ads or traditional paywalls. Instead, it uses small, unused resources from users' devices, such as bandwidth and processing power, with their explicit consent. Users have full control over participation.
Learn more: [Quickstart Guide](https://docs.joinmassive.com/monetization-sdk/quickstart)
# What permissions does the Massive SDK require on Android/Fire OS?
Source: https://docs.joinmassive.com/kb/sdk/what-permissions-does-the-massive-sdk-require-on-androidfire-os
The following permissions are needed:
* `android.permission.INTERNET`
* `android.permission.ACCESS_NETWORK_STATE`
* `android.permission.FOREGROUND_SERVICE`
* `android.permission.FOREGROUND_SERVICE_DATA_SYNC`
* `android.permission.WAKE_LOCK`
Learn more: [Android Permissions](https://docs.joinmassive.com/monetization-sdk/mobile-android#permissions-needed).
# What should I test before releasing my app with the SDK?
Source: https://docs.joinmassive.com/kb/sdk/what-should-i-test-before-releasing-my-app-with-the-sdk
Key testing areas:
1. Initialization flow
2. User consent implementation
3. Background/Foreground behavior
4. Network usage tracking
5. Error handling
6. Start/stop functionality
7. State persistence
Test on various devices and OS versions for each platform.
Sample applications are available for reference:
* [Android/FireOS Sample](https://docs.joinmassive.com/monetization-sdk/tv-fire#sample-application)
* [Windows Sample](https://docs.joinmassive.com/monetization-sdk/desktop-windows#getting-started)
* [iOS Sample](https://docs.joinmassive.com/monetization-sdk/mobile-ios#latest-release)
# Where can I find sample applications?
Source: https://docs.joinmassive.com/kb/sdk/where-can-i-find-sample-applications
Sample applications are available for all platforms:
* [Android/Fire OS Sample](https://docs.joinmassive.com/monetization-sdk/tv-fire#sample-application)
* [iOS Sample](https://docs.joinmassive.com/monetization-sdk/mobile-ios#latest-release)
* [Windows Sample](https://docs.joinmassive.com/monetization-sdk/desktop-windows#getting-started)
# Which platforms does the Massive SDK support?
Source: https://docs.joinmassive.com/kb/sdk/which-platforms-does-the-massive-sdk-support
The Massive SDK supports:
* Android
* Fire OS
* Windows
* iOS
Platform-specific integration guides:
* [Android Integration Guide](https://docs.joinmassive.com/monetization-sdk/mobile-android)
* [Fire OS Integration Guide](https://docs.joinmassive.com/monetization-sdk/tv-fire)
* [Windows Integration Guide](https://docs.joinmassive.com/monetization-sdk/desktop-windows)
* [iOS Integration Guide](https://docs.joinmassive.com/monetization-sdk/mobile-ios)
# Do I need a special ProGuard configuration for Android/Fire OS?
Source: https://docs.joinmassive.com/kb/technical/do-i-need-a-special-proguard-configuration-for-androidfire-os
Yes, if not use the R8 compiler. Required rules include:
* Keeping all "com.joinmassive.sdk" classes
* Keeping OkHttp3 and Moshi classes
* Preserving annotations and exceptions
If using R8, rules are automatically applied.
Learn more: [Android Technical Details](https://docs.joinmassive.com/monetization-sdk/mobile-android#technical-details)
# How can I combine different targeting features?
Source: https://docs.joinmassive.com/kb/technical/how-can-i-combine-different-targeting-features
Example combinations:
1. Device with Location:
```java
{USERNAME}-device-mobile-country-GB-city-London:{PASSWORD}
```
2. Device with Session:
```java
{USERNAME}-device-mobile-session-123:{PASSWORD}
```
3. Complete Integration:
```java
curl -x https://network.joinmassive.com:65535 \
-U '{USERNAME}-device-mobile-country-US-subdivision-NY-session-876:{PASSWORD}' \
https://cloudflare.com/cdn-cgi/trace
```
# How do I authenticate and verify my connection to Massive Network?
Source: https://docs.joinmassive.com/kb/technical/how-do-i-authenticate-and-verify-my-connection-to-massive-network
1. Authentication Requirements:
* PROXY\_USERNAME and PROXY\_PASSWORD (found in [Profile](https://partners.joinmassive.com/profile) section)
* Choose the appropriate port:
* 65535 for HTTPS
* 65534 for HTTP
* 65533 for SOCKS5
* 1080 when default ports are blocked by firewall
2. Verification Steps:
```bash
curl -x "https://network.joinmassive.com:65535" -U "PROXY_USERNAME:PROXY_PASSWORD" http://ip-api.com
```
Successful connection will return your IP information
Error **407** indicates invalid credentials.
# How do I authenticate with ISP proxies?
Source: https://docs.joinmassive.com/kb/technical/how-do-i-authenticate-with-isp-proxies
Massive ISP proxies support three protocols:
1. HTTP (Port 8000):
```bash
curl --proxy http://isp.joinmassive.com:8000 -U '{PROXY_USERNAME}:{PROXY_PASSWORD}' https://cloudflare.com/cdn-cgi/trace
```
2. HTTPS (Port 4080):
```bash
curl --proxy https://isp.joinmassive.com:4080 -U '{PROXY_USERNAME}:{PROXY_PASSWORD}' https://cloudflare.com/cdn-cgi/trace
```
3. SOCKS5 (Port 8000):
```bash
curl -x socks5h://isp.joinmassive.com:8000 -U '{PROXY_USERNAME}:{PROXY_PASSWORD}' https://www.cloudflare.com/cdn-cgi/trace
```
Replace `PROXY_USERNAME` and `PROXY_PASSWORD` with your credentials.
# How do I configure Massive residential proxies in Foxy Proxy?
Source: https://docs.joinmassive.com/kb/technical/how-do-i-configure-massive-residential-proxies-in-foxy-proxy
Follow these steps:
1. Installation:
* Install Foxy Proxy from browser extension store
2. Configuration:
* Click extension icon → "Options" → "Proxies" → "Add"
* Enter details:
* Title: "Massive Proxies"
* Type: HTTP, HTTPS, or SOCKS5
* Hostname: network.joinmassive.com
* Ports:
* HTTP: 65534
* HTTPS: 65535
* SOCKS5: 65533
* Username: Your proxy username
* Password: Your API key
* Save configuration
3. Usage:
* Activate: Select your configuration from extension icon
* Deactivate: Select "Disable"
* Verify: Check your IP at [https://ip-api.com/](https://ip-api.com/)
### Troubleshooting Foxy Proxy
If settings aren't working:
1. Review configuration in Options
2. Save changes
3. Restart browser completely
4. Verify IP at [https://ip-api.com/](https://ip-api.com/)
# How do I configure Massive residential proxies in SwitchyOmega?
Source: https://docs.joinmassive.com/kb/technical/how-do-i-configure-massive-residential-proxies-in-switchyomega
Follow these steps:
1. Installation:
* Install SwitchyOmega from Chrome Web Store
2. Initial Setup:
* Open SwitchyOmega dashboard
* Click "New Profile"
* Name it (e.g., "Massive Proxies")
* Click "Create"
3. Configuration:
* Protocol: Select HTTP, HTTPS, or SOCKS5
* Server: network.joinmassive.com
* Ports:
* HTTP: 65534
* HTTPS: 65535
* SOCKS5: 65533
* Authentication:
* Click "Lock" icon
* Enter Username and API key
* Save changes
* Click "Apply Changes"
4. Usage:
* Activate: Select your profile from extension icon
* Deactivate: Select "Direct" from extension icon
* Verify: Check your IP at [https://ip-api.com/](https://ip-api.com/)
### Troubleshooting SwitchyOmega
If settings aren't working:
1. Verify configuration details
2. Click "Apply Changes"
3. Restart browser completely
4. Verify IP at [https://ip-api.com/](https://ip-api.com/)
# How do I implement geotargeting?
Source: https://docs.joinmassive.com/kb/technical/how-do-i-implement-geotargeting
Two syntax options are available:
1. Dash Syntax:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{USERNAME}-country-US-subdivision-CA:{PASSWORD}' \
https://cloudflare.com/cdn-cgi/trace
```
2. Query String Syntax:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{USERNAME}?country=US&subdivision=CA:{PASSWORD}' \
https://cloudflare.com/cdn-cgi/trace
```
Learn more at [Geotargeting documentation](https://docs.joinmassive.com/residential/geotargeting)
# How do I implement sticky sessions?
Source: https://docs.joinmassive.com/kb/technical/how-do-i-implement-sticky-sessions
Basic Format:
```bash
PROXY_USERNAME-session-YOUR_ID:PASSWORD
```
Complete Example with All Parameters:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{USERNAME}-session-37-sessionttl-30-sessionmode-flex:{PASSWORD}' \
https://cloudflare.com/cdn-cgi/trace
```
Parameters Explained:
* session-37: Unique session identifier
* sessionttl-30: 30-minute session duration
* sessionmode-flex: Flexible session mode
* Port 65535: HTTPS (Use 65534 for HTTP, 65533 for SOCKS5)
# How do I set up HTTPS proxy authentication with Massive Network?
Source: https://docs.joinmassive.com/kb/technical/how-do-i-set-up-https-proxy-authentication-with-massive-network
To authenticate using Massive Network's **HTTPS proxy**, follow these steps:
### **Step 1: Use the Correct Port**
* For **HTTPS proxy connections**, always use **port 65535**.
* Do not use ports assigned to other protocols, such as HTTP (65534) or SOCKS5 (65533).
### **Step 2: Run the Authentication Command**
Use the following `curl` command to authenticate your **HTTPS proxy** connection:
```bash
curl --proxy https://network.joinmassive.com:65535 -U 'PROXY_USERNAME:PROXY_PASSWORD' https://cloudflare.com/cdn-cgi/trace
```
* Replace PROXY\_USERNAME and `PROXY_PASSWORD` with your credentials.
* Retrieve your credentials from the **Profile section** of the Massive Network dashboard: [https://partners.joinmassive.com/profile](https://partners.joinmassive.com/profile).
### **Step 3: Generate a Custom Command (Optional)**
* For advanced customization (e.g., location targeting or protocol preferences), visit the **Quickstart section** in your dashboard: [https://partners.joinmassive.com/quickstart](https://partners.joinmassive.com/quickstart).
Use the **Massive Proxy Configurator** to create tailored commands based on your specific needs.
# How do I set up proxy authentication with Residential Proxies?
Source: https://docs.joinmassive.com/kb/technical/how-do-i-set-up-proxy-authentication-with-residential-proxies
Choose your protocol and follow these steps:
**Protocol Ports:**
* HTTPS: 65535
* HTTP: 65534
* SOCKS5: 65533
**Authentication Commands:**
1. HTTPS:
```bash
curl --proxy https://network.joinmassive.com:65535 -U 'PROXY_USERNAME:PROXY_PASSWORD' https://cloudflare.com/cdn-cgi/trace
```
2. HTTP:
```bash
curl --proxy http://network.joinmassive.com:65534 -U 'PROXY_USERNAME:PROXY_PASSWORD' https://cloudflare.com/cdn-cgi/trace
```
3. SOCKS5:
```bash
curl -x socks5h://network.joinmassive.com:65533 -U 'PROXY_USERNAME:PROXY_PASSWORD' https://cloudflare.com/cdn-cgi/trace
```
**Setup Steps:**
1. Get your credentials from [Profile](http://partners.joinmassive.com/profile) tab
2. Replace `PROXY_USERNAME` and `PROXY_PASSWORD` in the command
3. Optional: Visit [Quickstart](http://partners.joinmassive.com/quickstart) for custom configurations
# How should I organize and implement subaccounts?
Source: https://docs.joinmassive.com/kb/technical/how-should-i-organize-and-implement-subaccounts
You can organize subaccounts based on different strategies:
1. Client/Environment Segmentation:
```bash
{USERNAME}-subaccount-clientA_production:{PASSWORD}
{USERNAME}-subaccount-clientA_staging:{PASSWORD}
```
2. Department/Project Structure:
```bash
{USERNAME}-subaccount-marketing_analytics:{PASSWORD}
{USERNAME}-subaccount-project_alpha_dev:{PASSWORD}
```
3. Advanced Implementations (**with targeting**):
```bash
# Geographic targeting
{USERNAME}-subaccount-client1-country-US:{PASSWORD}
# Device targeting
{USERNAME}-subaccount-client1-device-mobile:{PASSWORD}
# Combined parameters
{USERNAME}-subaccount-client1-country-US-device-mobile-session-123:{PASSWORD}
```
Here are complete examples showing how to use subaccounts in actual requests:
1. Basic Implementation:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{USERNAME}-subaccount-projectX:{PASSWORD}' \
https://cloudflare.com/cdn-cgi/trace
```
2. With Customer Tracking:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{USERNAME}-subaccount-customer@example.com:{PASSWORD}' \
https://cloudflare.com/cdn-cgi/trace
```
# Using Massive Residential Proxies with Playwright
Source: https://docs.joinmassive.com/kb/technical/using-massive-residential-proxies-with-playwright
The playwright supports both synchronous and asynchronous scraping. Here's an asynchronous example:
### Step 1: Install Playwright
Run:
```bash
pip install playwright
python -m playwright install
```
### Step 2: Code Example
```python
import asyncio
from playwright.async_api import async_playwright
async def main():
proxy = {
"server": "https://network.joinmassive.com:65535",
"username": "",
"password": ""
}
async with async_playwright() as p:
browser = await p.chromium.launch(proxy=proxy, headless=True)
page = await browser.new_page()
await page.goto("https://httpbin.io/ip")
content = await page.content()
print(content)
await browser.close()
asyncio.run(main())
```
### Troubleshooting Common Issues
1. **Invalid Proxy Credentials**:
* Ensure your username and password match the Massive dashboard credentials.
2. **Connection Refused**:
* Verify the protocol (`http` or `https`) and port (`65534` or `65535`).
3. **SSL Certificate Errors**:
* For headless browsers, configure them to ignore SSL certificate issues.
4. **IP Rotation Settings**:
* Adjust Sticky TTL in the Massive dashboard to control how often IPs rotate.
5. **Outdated Library Versions**:
Ensure libraries like `requests`, `puppeteer`, or `playwright` are up-to-date.
# Using Massive Residential Proxies with Puppeteer
Source: https://docs.joinmassive.com/kb/technical/using-massive-residential-proxies-with-puppeteer
Puppeteer, a popular headless browser library, can use Massive proxies to bypass anti-bot restrictions.
### Step 1: Install Puppeteer
Ensure Puppeteer is installed. Run:
```bash
npm install puppeteer
```
### Step 2: Configure Proxy
Use Puppeteer's `--proxy-server` flag for proxy setup, and authenticate with your Massive credentials.
### Step 3: Code Example
```javascript
import puppeteer from "puppeteer";
(async () => {
const browser = await puppeteer.launch({
args: [`--proxy-server=network.joinmassive.com:65534`],
});
const page = await browser.newPage();
await page.authenticate({ username: '', password: '' });
await page.goto("https://httpbin.io/ip");
const body = await page.waitForSelector("body");
const response = await body.getProperty("textContent");
const jsonResponse = await response.jsonValue();
console.log(jsonResponse);
await browser.close();
})();
```
### Troubleshooting:
If you encounter SSL certificate errors (e.g., `net::ERR_CERT_AUTHORITY_INVALID`), add the following:
```javascript
const browser = await puppeteer.launch({
args: [`--proxy-server=network.joinmassive.com:65534`],
ignoreHTTPSErrors: true
});
```
Use HTTP and port 65534 when using Puppeteer with the proxies.
# Using Massive Residential Proxies with Scrapy
Source: https://docs.joinmassive.com/kb/technical/using-massive-residential-proxies-with-scrapy
Here's the clean Markdown version:
Scrapy is a powerful web scraping library that supports proxy integration through `meta` parameters or custom middleware.
### Method 1: Using Meta Parameters
```python
import scrapy
class ScraperSpider(scrapy.Spider):
name = "scraper"
start_urls = ["https://httpbin.org/ip"]
def start_requests(self):
for url in self.start_urls:
yield scrapy.Request(
url=url,
callback=self.parse,
meta={
"proxy": "http://:@network.joinmassive.com:65534"
},
)
def parse(self, response):
self.logger.info(f"Response: {response.text}")
```
### Method 2: Custom Middleware
Update the `middlewares.py` with:
```python
class CustomProxyMiddleware:
def __init__(self):
self.proxy = 'http://:@network.joinmassive.com:65534'
def process_request(self, request, spider):
if 'proxy' not in request.meta:
request.meta['proxy'] = self.proxy
```
Add the middleware to `DOWNLOADER_MIDDLEWARES` in `settings.py`:
```python
DOWNLOADER_MIDDLEWARES = {
'myproject.middlewares.CustomProxyMiddleware': 350,
}
```
Note that, when using proxies with the Scrapy, always use host http and port 65534, which will work perfectly.
# Using Residential Proxies with Node.js and Axios
Source: https://docs.joinmassive.com/kb/technical/using-residential-proxies-with-nodejs-and-axios
Here's how you can integrate them with Node.js using Axios.
### Step 1: Install Axios
Ensure you have Node.js installed on your system. Navigate to your project directory and install Axios using the following command:
```bash
npm install axios
```
### Step 2: Get Your Proxy Credentials
Log in to the Massive dashboard and navigate to the **Profile** section to find your username, password, and proxy domain. Your proxy URL should follow this format:
```
https://:@network.joinmassive.com:65535
```
Replace `` and `` with your Massive credentials.
### Step 3: Make Requests with Massive Residential Proxies
Here's an example of using Axios with Massive proxies to send a request to `httpbin.io/ip`, which returns the IP address used for the request.
```javascript
const axios = require('axios');
// Proxy credentials
const proxy = {
protocol: 'https',
host: 'network.joinmassive.com',
port: '65535',
auth: {
username: '',
password: ''
}
};
// Target URL
const targetURL = 'https://httpbin.io/ip';
// Axios instance with SSL verification disabled
const axiosInstance = axios.create({
proxy: proxy,
httpsAgent: new (require('https').Agent)({
rejectUnauthorized: false // Disable SSL verification
})
});
// Make the request
axiosInstance.get(targetURL)
.then(response => {
console.log('Your IP Address:', response.data);
})
.catch(error => {
console.error('Error:', error.message);
});
```
### Troubleshooting Common Errors
Here are some common issues and their solutions:
### 1. Invalid Proxy Credentials
* If you see a `407 Proxy Authentication Required` or `401 Unauthorized` error, ensure your username and password in the `auth` section match the credentials in the Massive dashboard.
### 2. Outdated Axios Version
* Older Axios versions might not support all proxy configurations. Update Axios to the latest version using: `npm install axios@latest`
### 3. Connection Refused or Blocked
* Verify that you're using the correct protocol (`http` or `https`) and port (`65534` or `65535`).
* Check if the target website is blocking proxies. Some websites implement advanced anti-bot mechanisms.
### 4. Invalid Proxy URL Format
* The proxy URL must be correctly formatted: `:port`
* Ensure no component is missing or incorrectly configured.
### 5. IP Rotation Issues
If IPs are not rotating as expected, check the **Sticky TTL** settings on Massive. Lower the TTL value to rotate IPs more frequently.
# What are Massive's proxy pool capabilities?
Source: https://docs.joinmassive.com/kb/technical/what-are-massives-proxy-pool-capabilities
Our proxy infrastructure includes:
1. Residential Proxy Pool:
* 750,000+ unique IPs daily
* Unlimited concurrent connections
* Full access to entire proxy pool
* No sub-pool restrictions
2. ISP Proxy Pool:
* 20,000 dedicated IPs
* Flexible allocation options:
* Dedicated IP assignments
* Shared pool access
* Customizable allocations
# What are sticky sessions and how do they work?
Source: https://docs.joinmassive.com/kb/technical/what-are-sticky-sessions-and-how-do-they-work
Sticky sessions (session persistence) maintain the same proxy IP for multiple requests.
**Key Features:**
1. Duration:
* Default TTL: 15 minutes
* Maximum TTL: 60 minutes
* Customizable via sessionttl parameter
2. Session Modes:
* Strict Mode (Default): Maintains exact IP consistency
* Flex Mode: Tolerates temporary issues, resets after 15 consecutive errors
For more details, refer to the [sticky sessions documentation](https://docs.joinmassive.com/residential/sticky-sessions).
# What are the rules for combining parameters?
Source: https://docs.joinmassive.com/kb/technical/what-are-the-rules-for-combining-parameters
When combining targeting parameters:
1. Mandatory Requirements:
* Country parameter is always required
* Additional parameters must be valid for the specified country
2. Parameter Hierarchy:
* ZIP/Postal code takes precedence over city
* Subdivision and city must match when both are used
3. Impact Considerations:
* More specific targeting reduces available proxy nodes
* Start with broad parameters and narrow as needed
# What are the usage restrictions for Massive Network proxies (ISP and Residential)?
Source: https://docs.joinmassive.com/kb/technical/what-are-the-usage-restrictions-for-massive-network-proxies-isp-and-residential
Our proxy networks have the following restrictions:
1. Protocol Support:
* ISP Proxies: UDP is restricted by default (contact support for access)
* Residential Proxies: Only HTTP(S) and SOCKS5 protocols are supported
2. Port Access:
* Standard ports (80 and 443) are available
* Non-standard ports (e.g., [example.com:8080](http://example.com:8080)) are blocked
* Port 25 is blocked on both networks
* For email testing, request access to Ports 587 or 465
3. Content Policy:
* Only legal and compliant activities are supported
* 452 Disallowed Content error will appear for restricted content
* The network is designed for "family-friendly" content
# What geotargeting parameters are supported?
Source: https://docs.joinmassive.com/kb/technical/what-geotargeting-parameters-are-supported
Massive Network supports various geographic parameters:
1. Country (Mandatory):
* Two-letter [ISO codes](https://www.iso.org/obp/ui/#search/code) (e.g., US, GB, CA)
* Required for all geotargeting requests
2. Optional Parameters:
* Subdivision/State: Alphanumeric codes (e.g., CA for California)
* City: Standard English spelling (case-insensitive)
* ZIP/Postal Code: Format varies by country:
* US: 5 digits (10001)
* UK: 2-4 characters (SW1A)
* Canada: 3 characters (M5V)
* Other countries have specific formats
Learn more at [Geotargeting documentation](https://docs.joinmassive.com/residential/geotargeting)
# What is device-type targeting?
Source: https://docs.joinmassive.com/kb/technical/what-is-device-type-targeting
This feature routes requests through specific device categories:
* Mobile: Smartphones and tablets
* Common: Desktop computers and laptops
* TV: Smart TVs and set-top boxes
Basic Implementation:
```java
{USERNAME}-device-[DEVICE_TYPE]:{PASSWORD}
```
For more details, refer to the documentation on [device-type targeting](https://docs.joinmassive.com/residential/device-type-targeting).
# What ports are available for email services?
Source: https://docs.joinmassive.com/kb/technical/what-ports-are-available-for-email-services
For email-related traffic, the following ports are available with prior approval:
* Port 587: SMTP with STARTTLS
* Port 465: SMTP over SSL/TLS
**Note:** Port 25 is blocked to prevent spam and abuse.
# What ports should I use for proxy connections?
Source: https://docs.joinmassive.com/kb/technical/what-ports-should-i-use-for-proxy-connections
The following ports are available:
1. HTTPS Protocol: Port 65535
2. HTTP Protocol: Port 65534
3. SOCKS5 Protocol: Port 65533
4. Alternative Port: 1080 (use when default ports are blocked by firewall)
# When do sticky sessions change nodes?
Source: https://docs.joinmassive.com/kb/technical/when-do-sticky-sessions-change-nodes
Sessions may change under these conditions:
1. TTL expiration
2. Request limit exceeded
3. Node unavailability
4. Mode-specific conditions:
* Flex Mode: After 15 consecutive errors
* Strict Mode: Immediate change on failure
# Which ports should I use for standard web traffic?
Source: https://docs.joinmassive.com/kb/technical/which-ports-should-i-use-for-standard-web-traffic
Only standard ports 80 (HTTP) and 443 (HTTPS) are allowed for communication.
# How can I prevent common errors before they occur?
Source: https://docs.joinmassive.com/kb/troubleshooting/how-can-i-prevent-common-errors-before-they-occur
Follow these best practices:
1. Always double-check:
* Credential format
* Port-protocol matching
* Routing parameters
2. Review content policy before:
* Using specific ports
* Accessing certain content types
* Implementing new protocols
3. Monitor response bodies and headers for detailed error information
# How do I handle errors and debugging?
Source: https://docs.joinmassive.com/kb/troubleshooting/how-do-i-handle-errors-and-debugging
### Windows:
MassiveStatus enum includes these error states:
* `INVALID_ARGS`: Invalid arguments passed to function
* `UNINITIALIZED_SERVICE`: Service not initialized
* `INITIALIZING_SERVICE`: Service is initializing
* `ALREADY_STARTED`: Node already started
* `CORRUPTED_INSTALLATION`: Installation is corrupted
* `INTERNAL_ERROR`: Internal error occurred
### Android/Fire OS:
* Provides callbacks for the `init`, `start`, and `stop` methods to handle errors.
### iOS:
* Provides callbacks for the `initAsync` method to handle errors.
* Requires checking the return values of the `start` and `stop` methods.
Learn more about error handling:
* [Android](https://docs.joinmassive.com/monetization-sdk/mobile-android#technical-details)
* [Windows](https://docs.joinmassive.com/monetization-sdk/desktop-windows#api-reference)
* [iOS](https://docs.joinmassive.com/monetization-sdk/mobile-ios#technical-details)
# How do I troubleshoot a connection failure?
Source: https://docs.joinmassive.com/kb/troubleshooting/how-do-i-troubleshoot-a-connection-failure
Follow these steps:
1. Verify Protocol-Port Matching:
* HTTPS: Port 65535
* HTTP: Port 65534
* SOCKS5: Port 65533
2. Check Credentials:
* Format: username:password
* Look for typos or spaces
* Verify in [Profile](https://partners.joinmassive.com/profile) section
3. Test Configuration:
```bash
curl -x "https://network.joinmassive.com:65535" -U "username:password" http://ip-api.com
```
# I'm getting a "CONNECT tunnel failed, response 407" error. How do I fix it?
Source: https://docs.joinmassive.com/kb/troubleshooting/im-getting-a-connect-tunnel-failed-response-407-error-how-do-i-fix-it
I'm getting a "CONNECT tunnel failed, response 407" error. How do I fix it?
This is an authentication error. To resolve:
1. Verify credentials format (username:password)
2. Check for correct port usage
3. Run test command to validate setup
4. If persisting, [contact support](https://forms.fillout.com/t/p8dRqBYs58us) with error details
# Incompatibility with Older Python Versions (Pre-3.9.3) and HTTPS Proxies
Source: https://docs.joinmassive.com/kb/troubleshooting/incompatibility-with-older-python-versions-pre-393-and-https-proxies
**Overview**
This article provides guidance on troubleshooting issues related to using a residential proxy network with Python, specifically focusing on scenarios where an older version of Python does not support HTTPS proxies. We also cover the usage of HTTP proxies as an alternative when upgrading Python is not feasible.
**Problem:**
Clients using older versions of Python (before 3.9.3) often face issues when attempting to use HTTPS proxies with the requests library. This is due to the lack of support for HTTPS proxies in older Python versions.
**Root Cause**
Python versions prior to 3.9.3 have limited support for HTTPS proxies, which can lead to issues such as slow response times or failures when making HTTPS requests. The requests library in these versions may struggle with proxying HTTPS connections, especially when using older versions of the library.
**Solution**
1. **Verify Python and requests Library Versions**
* Use Python 3.9.3 or later. If upgrading Python is not an option, use HTTP instead of HTTPS.
* Confirm the version of the requests library. While the latest version is recommended, the issue primarily lies with the Python version rather than the library.
2. **Switch to HTTP Proxy (Port 65534)**
* If upgrading Python is not possible due to dependency constraints, use the HTTP proxy on port 65534.
* The HTTP proxy works well with all versions of Python and does not require an upgrade.
* Modify the proxy configuration in the script to use HTTP as shown below:
> **Configuration Note:**
> While configuring your proxy settings in Python, it's important to note that even though the requests library expects both http and https keys in the configuration, you can set both keys to the HTTP proxy address (using port 65534). This configuration works correctly and ensures compatibility across different Python versions.
```python
#!/usr/bin/env python3
import urllib
import requests
username = urllib.parse.quote('PROXY_USERNAME')
password = 'API_KEY'
url = 'http://cloudflare.com/cdn-cgi/trace' # Insert your target URL here
host = 'network.joinmassive.com'
port = 65534 # Use HTTP port
proxy = f'http://{username}:{password}@{host}:{port}'
response = requests.get(url, proxies={'http': proxy, 'https': proxy})
print(response.content)
```
**Additional Notes**
* **Compatibility**: Be aware that while HTTP is less secure than HTTPS, it might be the only viable solution when working with older Python environments.
**Conclusion**
When encountering issues with HTTPS proxies in Python, especially in versions prior to 3.9.3, switching to an HTTP proxy (port 65534) can provide a quick and effective workaround. This approach maintains the functionality of your residential proxy network while avoiding the need for a Python version upgrade that might disrupt existing dependencies.
For further assistance or if you continue to experience issues, please [contact our support team](https://forms.fillout.com/t/p8dRqBYs58us).
# What are the most common error codes and how do I fix them?
Source: https://docs.joinmassive.com/kb/troubleshooting/what-are-the-most-common-error-codes-and-how-do-i-fix-them
Here are the main error codes and their solutions:
1. Authentication Error (407):
* Meaning: Your credentials are invalid
* Fix: Verify your username and password format
2. Bad Request (400):
* Meaning: Your request is malformed
* Fix: Check routing parameters and request syntax
3. Disallowed Content (452):
* Meaning: Request violates content policy
* Fix: Check for prohibited ports or restricted protocols
4. Server Issues:
* 500 (Internal Server Error): Wait and retry
* 502 (Bad Gateway): Network couldn't find suitable proxy
* 503 (Service Unavailable): Geotargeting too restrictive or high network demand
# What should I do if I encounter issues with the SDK?
Source: https://docs.joinmassive.com/kb/troubleshooting/what-should-i-do-if-i-encounter-issues-with-the-sdk
What should I do if I encounter issues with the SDK?
If you encounter any issues or need assistance:
* Submit a ticket: [Support Portal](https://forms.fillout.com/t/p8dRqBYs58us)
* Contact support: [support@joinmassive.com](mailto:support@joinmassive.com)
# What should I do if I receive a server error (500, 502, or 503)?
Source: https://docs.joinmassive.com/kb/troubleshooting/what-should-i-do-if-i-receive-a-server-error-500-502-or-503
The response depends on the error code:
* 500 (Internal Server Error):
* Wait a few minutes and retry
* Contact support if persistent
* 502 (Bad Gateway):
* Check if routing parameters are too restrictive
* Try again as it might be temporary node unavailability
* 503 (Service Unavailable):
* Review geotargeting specifications
* Try during lower demand periods
# What should I do if the SDK initialization fails?
Source: https://docs.joinmassive.com/kb/troubleshooting/what-should-i-do-if-the-sdk-initialization-fails
If initialization fails:
* Check if the API token is correct.
* Ensure the platform requirements are met
* Verify that all required permissions are granted.
# Select Your Platform
Source: https://docs.joinmassive.com/monetization-sdk/desktop
The Massive SDK is available on Windows, macOS and Linux.
Integrate in Windows.
Integrate in Mac (Objective-C).
Integrate in Mac (Swift).
# Mac (Objective-C)
Source: https://docs.joinmassive.com/monetization-sdk/desktop-mac-objective-c
Integrate Massive SDK into your Mac application with this guide.
## Example code
```objectivec
#import
...
MSVInitWithAPIToken(apiToken, ^(id massive, NSError *error) {
if (massive) {
massive.userOptedIn = YES;
massive.menuBarUsageShown = YES;
if (massive.menuBarUsageShown) massive.menuBarUsageShown = NO;
NSViewController *massiveViewController = [massive createUsageViewController];
[view addSubview:massiveViewController.view];
[massive pauseUsageForTimePeriod:MSVHour];
if (massive.usagePaused) [massive unpauseUsage];
if (massive.userOptedIn) massive.userOptedIn = NO;
}
});
```
## Getting started
1. Download the [latest SDK package][5].
2. Open the Xcode project you want to integrate the SDK into.
3. If your project navigator isn’t shown, go to **View** > **Navigators** >
**Show Project Navigator**.
4. Open the SDK package and drag the `Massive.framework` bundle into the
navigator.
5. If the **Copy items if needed** box and box for your app target aren’t
checked, check them.
6. Press the **Finish** button.
7. In the implementation file for your app delegate, import the SDK:
```objectivec
// Importing in Objective-C:
#import
```
8. In your `applicationDidFinishLaunching` method, start and wait till the SDK
is ready by calling the `MSVInitWithAPIToken` function and defining a
`MSVInitCompletionHandler` block:
```objectivec
// Starting in Objective-C:
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
...
MSVInitWithAPIToken(apiToken, ^(id massive, NSError *error) {
if (massive) {
...
}
});
...
}
```
9. When the user opts in, toggle the `userOptedIn` property on:
```objectivec
// Opting in in Objective-C:
massive.userOptedIn = YES;
```
10. Next, show user tooling by toggling the `menuBarUsageShown` property on on
demand or calling the `getUsageViewController` method then adding the view
of the returned controller to your interface:
```objectivec
// Showing system tooling in Objective-C:
massive.menuBarUsageShown = YES;
// Showing custom tooling in Objective-C:
NSViewController *massiveViewController = [massive createUsageViewController];
[view addSubview:massiveViewController.view];
```
See the [API reference][6] for detailed info and optional SDK functionality.
## Sample apps
See the `README.txt` file and `Massive Sample` folder in the [SDK package][7].
## API reference
### Protocol
**`MSVNode`**
Defines a node of the Massive distributed computer.
***
### Types
**`typedef void (^MSVInitCompletionHandler)(id node, NSError *error);`**
A block called asynchronously after a Massive node has been started. The node,
if started successfully, or startup error, if not, is passed to the block.
***
**`typedef enum MSVTimePeriod: NSInteger { ... } MSVTimePeriod;`**
A capped or uncapped duration.
**Cases**
**`MSVIndefinite`** An indefinite time period.
**`MSVHour`** An hour.
**`MSVDay`** A day.
**`MSVWeek`** A week.
***
### Functions
**`void MSVInitWithAPIToken(NSString *apiToken, MSVInitCompletionHandler completion);`**
Starts a Massive node, pending user opt-in, attributed to your API token.
**Parameters**
**`apiToken`** A unique developer identifier obtained from this website.
**`completion`** A block called asynchronously after node startup.
***
### Properties
**`@property BOOL userOptedIn;`**
The state of user opt-in. `YES` allows computing resources to be
opportunistically consumed; `NO` doesn’t. Resource consumption is disallowed by
default; the user must agree to easy-to-understand terms of the exchange you’re
offering before you toggle this property on.
***
**`@property(readonly) BOOL usagePaused;`**
The enablement state of resource consumption. `YES` indicates usage is paused;
`NO`, unpaused.
***
**`@property BOOL menuBarUsageShown;`**
The visibility state of menu-bar tooling. `YES` adds charts representing
resource consumption to the user’s menu bar; `NO` removes them. Resource charts
aren’t made available by default; they must be added to the menu bar by toggling
this property on or to your interface by calling the `createUsageViewController`
method.
***
### Methods
**`- (void)pauseUsageForTimePeriod:(MSVTimePeriod)timePeriod;`**
Disables opportunistic resource consumption for the finite time period or till
you call the `unpauseUsage` method. Resource consumption is enabled by default.
**Parameters**
**`timePeriod`** A capped or uncapped duration.
***
**`- (void)unpauseUsage;`**
Re-enables resource consumption if disabled.
***
**`- (NSViewController *)createUsageViewController;`**
Constructs a view controller with charts representing resource consumption that
you can add to your app’s interface. Resource charts must be added to your
interface by calling this method or to the menu bar by toggling the
`menuBarUsageShown` property on.
**Return value**
The view controller with resource charts.
[5]: https://downloads.joinmassive.com/sdk/macos/Massive%20SDK.dmg
[6]: #api-reference
[7]: #getting-started
# Mac (Swift)
Source: https://docs.joinmassive.com/monetization-sdk/desktop-mac-swift
Integrate Massive SDK into your Mac application with this guide.
## Example code
```swift
import Massive
...
MSVInit(apiToken: apiToken, completion: { (massive: MSVNode?, error: Error?) -> Void in
if massive != nil {
massive.userOptedIn = true
massive.menuBarUsageShown = true
if massive.menuBarUsageShown {
massive.menuBarUsageShown = false
}
let massiveViewController = massive.createUsageViewController()
view.addSubview(massiveViewController.view)
massive.pauseUsage(timePeriod: .hour)
if massive.usagePaused {
massive.unpauseUsage()
}
if massive.userOptedIn {
massive.userOptedIn = false
}
}
} as! MSVInitCompletionHandler)
```
## Getting started
1. Download the [latest SDK package][5].
2. Open the Xcode project you want to integrate the SDK into.
3. If your project navigator isn’t shown, go to **View** > **Navigators** >
**Show Project Navigator**.
4. Open the SDK package and drag the `Massive.framework` bundle into the
navigator.
5. If the **Copy items if needed** box and box for your app target aren’t
checked, check them.
6. Press the **Finish** button.
7. In the implementation file for your app delegate, import the SDK:
```swift
// Importing in Swift:
import Massive
```
8. In your `applicationDidFinishLaunching` method, start and wait till the SDK
is ready by calling the `MSVInit` function and defining a
`MSVInitCompletionHandler` block:
```swift
// Starting in Swift:
func applicationDidFinishLaunching(_ notification: Notification) {
...
MSVInit(apiToken: apiToken, completion: { (massive: MSVNode?, error: Error?) -> Void in
if massive != nil {
...
}
} as! MSVInitCompletionHandler)
...
}
```
9. When the user opts in, toggle the `userOptedIn` property on:
```swift
// Opting in in Swift:
massive.userOptedIn = true
```
10. Next, show user tooling by toggling the `menuBarUsageShown` property on on
demand or calling the `getUsageViewController` method then adding the view
of the returned controller to your interface:
```swift
// Showing system tooling in Swift:
massive.menuBarUsageShown = true
// Showing custom tooling in Swift:
let massiveViewController = massive.createUsageViewController()
view.addSubview(massiveViewController.view)
```
See the [API reference][6] for detailed info and optional SDK functionality.
## Sample apps
See the `README.txt` file and `Massive Sample` folder in the [SDK package][7].
## API reference
### Protocol
**`MSVNode`**
Defines a node of the Massive distributed computer.
***
### Types
**`typealias MSVInitCompletionHandler = (MSVNode?, Error?) -> Void`**
A block called asynchronously after a Massive node has been started. The node,
if started successfully, or startup error, if not, is passed to the block.
***
**`enum MSVTimePeriod: Int`**
A capped or uncapped duration.
**Cases**
**`case indefinite`** An indefinite time period.
**`case hour`** An hour.
**`case day`** A day.
**`case week`** A week.
***
### Functions
**`func MSVInit(apiToken: String, completion: MSVInitCompletionHandler)`**
Starts a Massive node, pending user opt-in, attributed to your API token.
**Parameters**
**`apiToken`** A unique developer identifier obtained from this website.
**`completion`** A block called asynchronously after node startup.
***
### Properties
**`var userOptedIn: Bool { get set }`**
The state of user opt-in. `true` allows computing resources to be
opportunistically consumed; `false` doesn’t. Resource consumption is disallowed
by default; the user must agree to easy-to-understand terms of the exchange
you’re offering before you toggle this property on.
***
**`var usagePaused: Bool { get }`**
The enablement state of resource consumption. `true` indicates usage is paused;
`false`, unpaused.
***
**`var menuBarUsageShown: Bool { get set }`**
The visibility state of menu-bar tooling. `true` adds charts representing
resource consumption to the user’s menu bar; `false` removes them. Resource
charts aren’t made available by default; they must be added to the menu bar by
toggling this property on or to your interface by calling the
`createUsageViewController` method.
***
### Methods
**`func pauseUsage(timePeriod: MSVTimePeriod)`**
Disables opportunistic resource consumption for the finite time period or till
you call the `unpauseUsage` method. Resource consumption is enabled by default.
**Parameters**
**`timePeriod`** A capped or uncapped duration.
***
**`func unpauseUsage()`**
Re-enables resource consumption if disabled.
***
**`func createUsageViewController() -> NSViewController`**
Constructs a view controller with charts representing resource consumption that
you can add to your app’s interface. Resource charts must be added to your
interface by calling this method or to the menu bar by toggling the
`menuBarUsageShown` property on.
**Return value**
The view controller with resource charts.
[5]: https://downloads.joinmassive.com/sdk/macos/Massive%20SDK.dmg
[6]: #api-reference
[7]: #getting-started
# Windows (C/C++)
Source: https://docs.joinmassive.com/monetization-sdk/desktop-windows
Integrate Massive SDK into your Windows application with this guide.
## Example code
```c
#include
...
void initCallback(MassiveStatus status, void *context) {
if (status == MassiveStatus::OP_SUCCESS) {
if (MassiveStart() != MassiveStatus::OP_SUCCESS) {
MassiveShowTaskbarUsage();
bool isTaskbarUsageShown = false;
MassiveIsTaskbarUsageShown(&isTaskbarUsageShown);
if (isTaskbarUsageShown) MassiveHideTaskbarUsage();
bool isMassiveStarted = false;
MassiveIsStarted(&isMassiveStarted);
if (isMassiveStarted) MassiveStop();
}
}
}
MassiveOptions options = MassiveOptions::STOP_MASSIVE_ON_APP_QUIT;
MassiveInitWithAPIToken(apiToken, options, initCallback, context);
...
MassiveCleanUp();
```
## Getting started
1. Download the [latest SDK package][3].
2. Extract the package to your folder of choice.
3. Open your IDE and the project you want to integrate the SDK into.
4. Add the extracted `include` folder to your include path.
5. Add the `lib\win64` folder to your library path and, from that folder, the `MassiveClient.dll`
library as a dependency.
6. Configure the `MassiveInstaller.exe` installer to be copied, at build time, from the `bin` to
output folders.
7. In your implementation file, import the SDK:
```c
// Importing in C/C++:
#include
```
8. Start and wait till the SDK is ready by calling the `MassiveInitWithAPIToken` function and
defining a `MassiveInitCallback` continuation function:
```c
// Starting in C/C++:
MassiveInitWithAPIToken(apiToken, options, initCallback, context);
void initCallback(MassiveStatus status, void *context) {
if (status == MassiveStatus::OP_SUCCESS) {
...
}
}
```
9. When the user opts in, call the `MassiveStart` function:
```c
// Opting in in C/C++:
MassiveStart();
```
10. Next, show user tooling by calling the `MassiveShowTaskbarUsage` function on demand:
```c
// Showing system tooling in C/C++:
MassiveShowTaskbarUsage();
```
See the [API reference][6] for detailed info and optional SDK functionality.
## Sample apps
See the `README.txt` file and `samples` folder in the [SDK package][7]. The
samples demonstrate how to integrate the SDK into your project and use its
functionality.
* `MassiveCliSample` is a simple console application that demonstrates how to
integrate the SDK into a C/C++ project.
* `MassiveSample` is a simple Windows application that demonstrates how to
integrate the SDK into a C# project.
## API reference
### Types
**`typedef enum MassiveStatus`**
An enumeration of possible states of the Massive SDK.
**Values**
**`OP_SUCCESS`** The operation was successful.
**`INVALID_ARGS`** The arguments passed to the function were invalid.
**`UNINITIALIZED_SERVICE`** The Massive service was not initialized.
**`INITIALIZING_SERVICE`** The Massive service is initializing.
**`ALREADY_STARTED`** The node is already started.
**`CORRUPTED_INSTALLATION`** The installation is corrupted.
**`INTERNAL_ERROR`** An internal error occurred.
***
**`typedef enum MassiveOptions`**
An enumeration of options for the Massive SDK initialization.
**Values**
**`NONE`** No options.
**`STOP_MASSIVE_ON_APP_QUIT`** Stops the Massive service when the client app quits.
***
**`typedef void(__cdecl *MassiveInitCallback)(MassiveStatus status, void *context);`**
A function called asynchronously after a node of the Massive network
has been initialized. The startup state and local data from the caller are
passed to the function.
**Parameters**
**`status`** The startup state of the node.
**`context`** Any local data passed to the `MassiveInitWithAPIToken` function.
***
**`typedef void(__cdecl *MassiveCallback)(void *context);`**
Type of generic callback that is used to handle async events from the SDK.
**Parameters**
**`context`** Any local data passed to the function which uses this callback.
***
### Functions
**`void __cdecl MassiveInitWithAPIToken(const char *apiToken, const MassiveOptions options, MassiveInitCallback callback, void *context);`**
Starts a Massive node, pending user opt-in, attributed to your API token.
**Parameters**
**`apiToken`** A unique developer identifier obtained from this website.
**`options`** Options for the Massive SDK initialization.
**`callback`** A function called asynchronously after node startup.
**`context`** Any local data to pass to the `callback` function.
***
**`void __cdecl MassiveCleanUp();`**
De-initializes and releases all resources acquired by Massive.
***
**`const char *__cdecl MassiveGetVersion();`**
Returns the version of the Massive SDK.
**Return value**
The version of the Massive SDK in the format `major.minor.patch`.
***
**`MassiveStatus __cdecl MassiveStart();`**
Allows computing resources to be opportunistically consumed. The user must agree
to easy-to-understand terms of the exchange you’re offering before you call this
function.
**Return value**
Execution status code.
***
**`MassiveStatus __cdecl MassiveStop();`**
Disallows computing resources to be consumed.
**Return value**
Execution status code.
***
**`MassiveStatus __cdecl MassiveIsStarted(bool *isStarted);`**
Queries the allowing state of the computing resources sharing.
**Return value**
Execution status code.
***
**`MassiveStatus __cdecl MassiveShowTaskbarUsage();`**
Adds charts representing resource consumption to the user’s taskbar. Resource
charts must be made available by calling this function.
**Return value**
Execution status code.
***
**`MassiveStatus __cdecl MassiveHideTaskbarUsage();`**
Hides charts representing resource consumption from the user's taskbar.
**Return value**
Execution status code.
***
**`MassiveStatus __cdecl MassiveIsTaskbarUsageShown(bool *isShown);`**
Queries the visibility state of taskbar tooling.
**Return value**
Execution status code.
***
**`MassiveStatus __cdecl MassiveStoppedViaTaskbarCallback(MassiveCallback callback, void *context);`**
Sets a callback to be called when user opts out from Massive using Taskbar UI.
**Parameters**
**`callback`** A callback to notify about the event.
**`context`** Any local data to pass to the `callback` function.
**Return value**
Execution status code.
***
**`MassiveStatus __cdecl MassiveStartedViaTaskbarCallback(MassiveCallback callback, void *context);`**
Sets a callback to be called when user opts in to Massive using Taskbar UI.
**Parameters**
**`callback`** A callback to notify about the event.
**`context`** Any local data to pass to the `callback` function.
**Return value**
Execution status code.
***
**`MassiveStatus __cdecl MassiveSetServiceUnavailableCallback(MassiveCallback callback, void *context);`**
Sets a callback to be called when connection to the Massive is lost.
**Parameters**
**`callback`** A callback to notify about the event.
**`context`** Any local data to pass to the `callback` function.
**Return value**
Execution status code.
***
**`MassiveStatus __cdecl MassiveSetServiceAvailableCallback(MassiveCallback callback, void *context);`**
Sets a callback to be called when connection to the Massive is restored.
**Parameters**
**`callback`** A callback to notify about the event.
**`context`** Any local data to pass to the `callback` function.
**Return value**
Execution status code.
[3]: https://downloads.joinmassive.com/sdk/windows/MassiveSDK.zip
[6]: #api-reference
[7]: #getting-started
# Introduction
Source: https://docs.joinmassive.com/monetization-sdk/introduction
The Massive SDK provides a new way to monetize app features and content without annoying ads or low-converting paywalls.
# About Us
Your users who opt in pay with an imperceptible amount of their computing power and bandwidth rather than with their personal attention and data.
Massive combines these computing resources to form a supercomputer that monitors internet performance, gathers business intelligence, trains AI models, runs scientific simulations, and performs other distributed tasks. You can access your developer dashboard anytime to check the daily revenue you’ve generated.
The SDK takes care of performing tasks imperceptibly by analyzing anonymous telemetry data. You’re responsible for making sure users are prompted with clear terms before opting in then can pause, opt out of, and access tooling to visualize resource consumption.
# Getting started
The first step to using Massive Network is making sure you have been approved to use our SDK. If you haven't done so already, [create an account](https://partners.joinmassive.com/create-account-sdk) and if you have signed up but do not have credentials email [support@joinmassive.com](support@joinmassive.com).
# Select Your Platform
Source: https://docs.joinmassive.com/monetization-sdk/mobile-and-smart-tv
The Massive SDK is available on Android, FireOS, and iOS.
Integrate in Android.
Integrate in iOS.
Integrate in Fire OS.
# Android
Source: https://docs.joinmassive.com/monetization-sdk/mobile-android
Integrate Massive SDK into your Android application with this guide.
## Technical Requirements
| | |
| ----------------- | ------------------------ |
| Android SDK Level | `21 (Lollipop)` or later |
| Kotlin version | `1.9.0` or later |
| Java version | `17` or later |
### Permissions Needed
| |
| ------------------------------------------------- |
| `android.permission.INTERNET` |
| `android.permission.ACCESS_NETWORK_STATE` |
| `android.permission.FOREGROUND_SERVICE` |
| `android.permission.FOREGROUND_SERVICE_DATA_SYNC` |
| `android.permission.WAKE_LOCK` |
## Integration Guide
### Sample application
| | | |
| ---------------------------------------- | -------------------------------------------- | -------------------------------------------------------------------------------------------- |
| | Sample Application Kotlin (Android / FireOS) | [Download](https://downloads.joinmassive.com/sdk/android/1.4.0/Massive-SampleApp.zip) |
| | Sample Application Flutter (Android) | [Download](https://downloads.joinmassive.com/sdk/android/1.4.0/Massive-SampleAppFlutter.zip) |
Massive SDK comes with a sample application showing project configuration, API integration, and consent screen.
To run the app, follow next steps:
1. Download the latest sample using the link above.
2. Unarchive and open the project in Android Studio.
3. Copy the API token from your [Profile](https://partners.joinmassive.com/profile).
4. Set the token value to the variable `API_TOKEN` at the end of `MainActivity.kt`.
5. Build and run a target `sampleapp`.
### Dependency configuration
Add the dependency to your project Gradle configuration:
1. Add Massive maven repo `https://downloads.joinmassive.com/sdk/android/release` to the dependency `repositories` used by the project.
It can be defined in different places depending on your project.
Common places are:
global **settings.gradle.kts**
```gradle
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven {
url = uri("https://downloads.joinmassive.com/sdk/android/release")
}
}
}
```
project **build.gradle**
```gradle
allprojects {
repositories {
google()
mavenCentral()
maven {
url uri("https://downloads.joinmassive.com/sdk/android/release")
}
}
}
```
2. In the build configuration file for your **app module** (*build.gradle.kts* / *build.gradle*), add the Massive SDK as a dependency:
```gradle
dependencies {
implementation("com.joinmassive:sdk:1.+")
}
```
**Note:** Make sure to add and configure the `org.jetbrains.kotlin.android` plugin to your app module.
```gradle
plugins {
id("org.jetbrains.kotlin.android")
}
android {
...
kotlinOptions {
jvmTarget = "1.8"
}
}
```
If you use a `toml` file for dependency configuration, add the following to the `toml`:
```gradle
[versions]
massiveSdk = "massive_sdk_version_here"
[libraries]
massive-sdk = { group = "com.joinmassive", name = "sdk", version.ref = "massiveSdk"}
```
Then, define SDK dependency in the `gradle` file as:
```gradle
dependencies {
implementation(libs.massive.sdk)
}
```
### Integration to the app
#### 1. Get the API token
Massive SDK API token is available in your [Profile](https://partners.joinmassive.com/profile).
#### 2. Initialize MassiveClient
Interaction with Massive SDK starts with initializing the `MassiveClient` in your `Activity` or `Application` class. Ensure you do this at the start of the application lifecycle.
```kotlin
class MainActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Initialize MassiveClient
MassiveClient.init(API_TOKEN, this)
}
}
```
#### 3. Create client options
Next, fill in the client options to specify the desired running mode: *Foreground* or *Background* service.
*Foreground* service is preferable as it increases the earning potential. You can find more information about the difference in the [Technical details](#technical-details).
```kotlin
val massiveOptions = MassiveOptions(
serviceType = MassiveServiceType.Foreground,
notificationOptions = MassiveNotificationOptions(
notificationTitle = getString(R.string.notification_title),
notificationText = getString(R.string.notification_content),
iconDrawable = com.joinmassive.sdk.R.drawable.massive_sdk_icon
)
)
```
#### 4. Request consent from the user
Before starting the client, obtain user consent for the terms of resource exchange. Please see our [launch checklist](https://www.joinmassive.com/launch-checklist-android) for additional details.
Here is the sample consent screen:

Example consent text
```
To remove ads and get free content, please let Massive use a small amount of your device's free resources and IP
address to download public web data from the internet.
This supports the development of Application and helps us to improve our services.
No personal information is collected except your IP address.
Your participation is optional, and you may opt out anytime by accessing Settings (see Massive's FAQ for details).
Pressing Accept indicates that you agree to Massive's license and privacy policy.
```
#### 5. Start usage after consent
After receiving the user's consent, start usage using the `start()` method and created options:
```kotlin
// Check if there is user consent to use Massive and show the dialog if we need to request it.
if (!consentHelper.isConsentGiven()) {
consentHelper.showConsentDialog(
onAccept = {
// Start Massive if the user has given consent.
MassiveClient.start(massiveOptions) { result ->
result.onSuccess {
// Handle successful start.
}.onFailure { exception ->
// Handle start failure.
}
}
},
onDecline = {}
)
} else {
// If the user has already given consent, start Massive directly.
MassiveClient.start(massiveOptions) { result ->
result.onSuccess {
// Handle successful start.
}.onFailure { exception ->
// Handle start failure.
}
}
}
```
## Changes in the new Massive SDK 1.0
The new version of the Massive SDK introduces several significant changes aimed at improving usability, performance, and integration flexibility. Here is an overview of the key changes:
1. Dependency configuration: The dependency configuration process has been streamlined. Instead of manually setting up a local Maven repository, you can now directly add the Massive Maven repository to your project’s Gradle configuration. This simplification reduces setup time and potential errors, ensuring a more efficient integration of the SDK.
2. Changed package name: The name of the Massive SDK package has changed from `com.massive` to `com.joinmassive`.
3. Changed client interface: The `MassiveClient` has shifted from using a singleton instance to utilizing static methods. This change simplifies interaction with the SDK, making it more straightforward to initialize and manage the client throughout the application lifecycle.
4. Options handling: The process of providing options has been moved from the init stage to the `start` method. This allows for more dynamic configuration, enabling modification of the service options at the time of starting the client rather than during initialization. This separation ensures a quicker initialization process and more flexible configuration management.
5. Changed behavior of `stop`: The behavior of the stop method has been enhanced. In the new version, calling `stop` not only stops the usage but also shuts down the service entirely. This ensures that all operations are cleanly terminated and the service is properly shut down, providing a more robust mechanism for managing the SDK’s lifecycle.
6. Remote service: The Massive SDK service now runs as a separate process, enhancing the stability and performance of the main application.
### Migration from version 0.x
#### Dependency Configuration
* **Old Version**: Requires manually setting up a local Maven repository.
```bash
mkdir project/repo
unzip massive-sdk.zip -d project/repo
```
```gradle
repositories {
maven {
url = uri("/project/repo")
}
}
```
```gradle
dependencies {
implementation("com.massive:sdk:0.+")
}
```
* **New Version**: Directly add the Massive Maven repository to the dependency `repositories`.
```gradle
repositories {
maven {
url = uri("https://downloads.joinmassive.com/sdk/android/release")
}
}
```
```gradle
dependencies {
implementation("com.joinmassive:sdk:1.+")
}
```
#### Initialization
* **Old Version**:
```kotlin
MassiveClient.getInstance(context) { client ->
client.initAsync(MASSIVE_DEMO_API_TOKEN, massiveOptions, object : InitCallback {
override fun onSuccess() {
// Handle successful initialization.
}
override fun onFailure(message: String) {
// Handle initialization failure.
}
})
}
```
* **New Version**:
```kotlin
MassiveClient.init(API_TOKEN, context)
```
#### Start and stop methods
* **Old Version**:
```kotlin
client.start()
...
client.stop()
```
* **New Version**:
```kotlin
MassiveClient.start(massiveOptions) {
it.onSuccess { // Handle Started state. }
it.onFailure { // Handle error. }
}
...
MassiveClient.stop() {
it.onSuccess { // Handle Stopped state. }
it.onFailure { // Handle error. }
}
```
#### State handling
* **Old Version**:
```kotlin
// Async state handler.
client.listener = object : MassiveClientListener {
override fun onStateChange(newState: State) {
// Handle changed state.
}
}
...
// Current state.
client.state
```
* **New Version**:
```kotlin
// Handle state after the action.
MassiveClient.start(massiveOptions) {
it.onSuccess { // Handle Started state or query the current state. }
it.onFailure { // Handle error. }
}
// Current state.
when (MassiveClinet.state()) {
MassiveClient.State.Starting -> {
}
MassiveClient.State.Started -> {
}
MassiveClient.State.Stopped -> {
}
}
```
## Technical details
1. Android permissions
Massive SDK defines the following permissions in the manifest file:
* `android.permission.INTERNET`
* `android.permission.ACCESS_NETWORK_STATE`
* `android.permission.FOREGROUND_SERVICE`
* `android.permission.FOREGROUND_SERVICE_DATA_SYNC`
* `android.permission.WAKE_LOCK`
These permissions will be automatically added to your app during the build.
2. Client initialization
Interaction with the SDK always begins with initialization using `MassiveClient.init`, which requires your API token. This initialization step is crucial and should be performed only once during the application’s lifecycle. Subsequent calls to `init` will have no effect. Attempting to re-initialize the SDK with a different API token will result in a `MassiveReinitException`, ensuring that the SDK maintains a single consistent state throughout the app’s runtime.
Since the SDK consists of client and service components, initialization can trigger synchronization of their states. To handle this scenario and achieve accurate state tracking, you can pass an additional callback to the `init` method. This callback will be called in the main thread after synchronization is complete.
3. User consent before starting the usage
Before starting the usage for the first time (using the `start()` method), it is mandatory to obtain user consent for the terms of resource exchange. This aligns with user privacy and control principles. Ensure that your application includes a clear and understandable consent mechanism.
```kotlin
if (isUserConsentGiven) {
MassiveClient.start(massiveOptions) {}
}
```
4. Starting and stopping the client
Initialization of the `MassiveClient` with the `init()` method does not automatically launch the service or start the usage.
**It prepares the SDK for use but does not begin its operation.**
To ensure that the Massive is running, the `start()` method must be called after initialization and on each application relaunch. The `start()` method is designed to be idempotent, meaning it is safe to call multiple times. If the service is already started, subsequent calls to start will have no effect, preventing redundant operations.
The `stop()` method is used to stop and kill the service, effectively halting all operations and ensuring that the service is properly terminated. After calling `stop()`, you can restart the client by calling the `start()` method again, and it is possible to provide different options for the restart. This flexibility allows you to change the configuration or operational mode of the SDK as needed.
5. Client options and service types
Massive SDK can operate either as a *Background* or a *Foreground* service. The choice depends on your app's requirements and how you want to manage the SDK's resource usage.
* *Foreground Service*: Allow Massive to run more and less likely killed by the system but more visible with a customizable notification ensuring the user is aware of the service's operation.
**Running as a Foreground Service increases earning potential.**
* *Background Service:* Less intrusive, running silently without user interaction.
6. Customizing Foreground Service Notification
When running as a foreground service, Massive SDK allows customization of the notification displayed to the user.
You can set the title, text, and icon of the notification:
```kotlin
val options = MassiveOptions(
serviceType = MassiveServiceType.Foreground,
notificationOptions = MassiveNotificationOptions(
notificationTitle = "Your Title",
notificationText = "Your Text",
iconDrawable = R.drawable.your_icon
)
)
```
Massive library contains a pre-defined drawable icon resource `com.joinmassive.sdk.R.drawable.massive_sdk_icon`, but you can also provide your own.
7. Usage tracking
The Massive SDK includes functionality for tracking and retrieving current traffic usage statistics. This allows you to monitor the SDK's data usage, providing insights into its network activity.
The `usage` method in the `MassiveClient` class fetches and returns the current traffic usage in *bytes*. Please check the sample application for an example of how to use the method to retrieve and display the traffic usage statistics.
8. SDK remote service
The latest version of the Massive SDK uses a remote service that is launched as a separate process. This service handles the core operations of the SDK independently of the main application process, providing better performance and stability.
9. ProGuard rules
Massive SDK AAR embeds required Android ProGuard rules which are applied automatically if you are using the R8 compiler.
If you, however, don’t use R8 you have to apply the rules below:
consumer-rules.pro
```gradle
# Keep the public SDK entities
-keep class com.joinmassive.sdk.** { *; }
-keep interface com.joinmassive.sdk.** { *; }
-keep enum com.joinmassive.sdk.** { *; }
-dontwarn org.jetbrains.annotations.**
-keep class kotlin.Metadata { *; }
# Keep OkHttp3 and Moshi classes
-keep class com.squareup.okhttp3.** { *; }
-keep interface com.squareup.okhttp3.** { *; }
-keep class com.squareup.moshi.** { *; }
-keep interface com.squareup.moshi.** { *; }
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,*Annotation*,EnclosingMethod
```
# iOS
Source: https://docs.joinmassive.com/monetization-sdk/mobile-ios
The Massive SDK provides a new way to monetize app features and content without annoying ads or low-converting paywalls.
## Latest release
| | | | |
| -------------------------------------- | ------------------------- | ------- | --------------------------------------------------------------------------------------------- |
| | iOS SDK | `0.3.1` | [Download](https://downloads.joinmassive.com/sdk/ios/0.3.1/MassiveSDK-iOS-0.3.1.zip) |
| | Sample iPhone Application | `0.3.1` | [Download](https://downloads.joinmassive.com/sdk/ios/0.3.1/MassiveSample-iPhoneAPP-0.3.1.zip) |
## Technical Requirements
| | |
| ---------------------- | --------------- |
| iOS Minimum Deployment | `16.0` |
| iOS Deployment Target | `16.0` or later |
| Swift version | `5.10` or later |
| Capabilities required | None |
## Integration Guide
### Dependency configuration in Xcode
To integrate the Massive SDK into your iOS project, set up the SDK as a dependency in the target's settings.
1. Go to the target's settings and select the `General` tab.
2. Drag and drop the Massive SDK `xcframework` file into the `Frameworks, Libraries, and Embedded Content` section.
3. Ensure that the `xcframework` is set to Embed & Sign.
### Integration to the app
Here's an example of how to integrate the Massive SDK into an iOS app. This sample demonstrates the essential steps such as initializing Massive, handling user consent, and starting or stopping the SDK.
#### 1. Obtain the API token
Massive SDK API token is available in your [Profile](https://partners.joinmassive.com/profile).
#### 2. Initialize MassiveClient
Initialize the client with the API token and handle the result in the callback:
```swift
MassiveClient.shared.initAsync(apiToken: {API_TOKEN}) { status in
switch status {
case .initialized:
// Handle successful initialization
case .error:
// Handle initialization error
default:
// Handle other states when massive is already initialized
}
}
```
#### 3. Request user consent
Before starting the SDK, obtain user consent for the terms of resource exchange.
Here is a sample consent screen:

#### 4. Start usage
After receiving user's consent, start usage using `start()` method:
```swift
// Check if the user gives consent to use Massive, and show the dialog if we need to request it.
if (!isConsentGiven()) {
showConsentDialog()
}
if (MassiveClient.shared.start()) {
// Handle successful start
}
```
#### 5. Query network usage
Having the SDK initialized, you can query the network usage anytime independently of the SDK state.
The usage is in bytes and can be converted to more suitable units for display.
```swift
let usage = MassiveClient.shared.getNetworkUsage()
let usageInBytes = Double(usage)
let usageInKB = usageInBytes / 1024
let usageInMB = usageInKB / 1024
let usageInGB = usageInMB / 1024
// Display the usage
```
#### 6. Stop usage
To stop the SDK, use the `stop()` method:
```swift
MassiveClient.shared.stop()
```
#### 7. Register a task to run in the background
First, enable the **background processing** mode in the app capabilities and add the `com.massive.sdk.startBackground` task ID to the list of permitted task identifiers.
Then, register a task to run in the background calling the `startBackground()` method in the provided closure. This must be done before the end of the app launch sequence.
```swift
let TASK_ID = "com.massive.sdk.startBackground"
BGTaskScheduler.shared.register(forTaskWithIdentifier: TASK_ID, using: nil) { task in
MassiveClient.shared.startBackground(task: task as! BGProcessingTask)
}
```
## Sample application
Massive SDK comes with a sample application showing project configuration, API integration, and consent screen.
The archive with the sample contains a *README* file with instructions to set up and run the application.
### Technical details
#### 1. Shared instance of the `MassiveClient`
The MassiveClient class is designed as a singleton, ensuring that only one instance of the client is active throughout the application's lifecycle. This design simplifies the management of the client's state and its interactions with the Massive network.
#### 2. One-time initialization
The SDK should be initialized only once per application launch. Attempts to reinitialize the SDK after a successful initialization will simply return its current state.
***The SDK must be reinitialized if the application is terminated and relaunched.***
#### 3. User Consent Before Starting SDK Usage
Before starting the SDK (using the `start()` method), it is mandatory to obtain user consent for the terms of resource exchange. This aligns with user privacy and control principles. Ensure that your application includes a clear and understandable consent mechanism.
```swift
if (isUserConsentGiven) {
MassiveClient.shared.start()
}
```
#### 4. State persistence
The SDK state persists when the application goes into the background. This ensures that the SDK continues to operate correctly when the application is resumed.
***The SDK state is not saved across different launches of the application.***
#### 5. Separate initialization and usage start
Initializing the SDK does not automatically start its operation. This separation allows you to initialize the SDK early in your app's lifecycle (e.g., during app startup) and start its operation only after obtaining user consent.
#### 6. Background processing
The SDK supports background processing to continue its operation when the application is in the background. The application is responsible for registering the background task, but the task scheduling is managed by the SDK.
***The background execution occurs only when the device is charging to preserve battery life.***
#### 7. Network usage data
The SDK provides network usage data in bytes and can be queried at any time after the SDK is initialized. The usage reported by the SDK is cumulative and represents the total network usage since the SDK was initialized for the first time.
***The data does not persist across application reinstalls.***
# Quickstart
Source: https://docs.joinmassive.com/monetization-sdk/quickstart
The Massive SDK is available on Windows, Android, FireOS, iOS, and Linux.
# Fire OS
Source: https://docs.joinmassive.com/monetization-sdk/tv-fire
Integrate Massive SDK into your Fire OS application with this guide.
## Technical Requirements
| | |
| ----------------- | ------------------------ |
| Android SDK Level | `21 (Lollipop)` or later |
| Kotlin version | `1.9.0` or later |
| Java version | `17` or later |
### Permissions Needed
| |
| ------------------------------------------------- |
| `android.permission.INTERNET` |
| `android.permission.ACCESS_NETWORK_STATE` |
| `android.permission.FOREGROUND_SERVICE` |
| `android.permission.FOREGROUND_SERVICE_DATA_SYNC` |
| `android.permission.WAKE_LOCK` |
## Integration Guide
### Sample application
| | | |
| ---------------------------------------- | -------------------------------------- | ------------------------------------------------------------------------------------- |
| | Sample Application (Android / Fire OS) | [Download](https://downloads.joinmassive.com/sdk/android/1.3.1/Massive-SampleApp.zip) |
Massive SDK comes with a sample application showing project configuration, API integration, and consent screen.
To run the app, follow next steps:
1. Download the latest sample using the link above.
2. Unarchive and open the project in Android Studio.
3. Copy the API token from your [Profile](https://partners.joinmassive.com/profile).
4. Set the token value to the variable `API_TOKEN` at the end of `MainActivity.kt`.
5. Build and run a target `sampleapp`.
### Dependency configuration
Add the dependency to your project Gradle configuration:
1. Add Massive maven repo `https://downloads.joinmassive.com/sdk/android/release` to the dependency `repositories` used by the project.
It can be defined in different places depending on your project.
Common places are:
global **settings.gradle.kts**
```gradle
dependencyResolutionManagement {
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
repositories {
google()
mavenCentral()
maven {
url = uri("https://downloads.joinmassive.com/sdk/android/release")
}
}
}
```
project **build.gradle**
```gradle
allprojects {
repositories {
google()
mavenCentral()
maven {
url uri("https://downloads.joinmassive.com/sdk/android/release")
}
}
}
```
2. In the build configuration file for your **app module** (*build.gradle.kts* / *build.gradle*), add the Massive SDK as a dependency:
```gradle
dependencies {
implementation("com.joinmassive:sdk:1.+")
}
```
If you use a `toml` file for dependency configuration, add the following to the `toml`:
```gradle
[versions]
massiveSdk = "massive_sdk_version_here"
[libraries]
massive-sdk = { group = "com.joinmassive", name = "sdk", version.ref = "massiveSdk"}
```
Then, define SDK dependency in the `gradle` file as:
```gradle
dependencies {
implementation(libs.massive.sdk)
}
```
### Integration to the app
#### 1. Get the API token
Massive SDK API token is available in your [Profile](https://partners.joinmassive.com/profile).
#### 2. Initialize MassiveClient
Interaction with Massive SDK starts with initializing the `MassiveClient` in your `Activity` or `Application` class. Ensure you do this at the start of the application lifecycle.
```kotlin
class MainActivity : Activity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
// Initialize MassiveClient
MassiveClient.init(API_TOKEN, this)
}
}
```
#### 3. Create client options
Next, fill in the client options to specify the desired running mode: *Foreground* or *Background* service.
*Foreground* service is preferable as it increases the earning potential. You can find more information about the difference in the [Technical details](#technical-details).
```kotlin
val massiveOptions = MassiveOptions(
serviceType = MassiveServiceType.Foreground,
notificationOptions = MassiveNotificationOptions(
notificationTitle = getString(R.string.notification_title),
notificationText = getString(R.string.notification_content),
iconDrawable = com.joinmassive.sdk.R.drawable.massive_sdk_icon
)
)
```
#### 4. Request consent from the user
Before starting the client, obtain user consent for the terms of resource exchange. Please see our [launch checklist](https://www.joinmassive.com/launch-checklist-android) for additional details.
Here is the sample consent screen:

Example consent text
```
To remove ads and get free content, please let Massive use a small amount of your device's free resources and IP
address to download public web data from the internet.
This supports the development of Application and helps us to improve our services.
No personal information is collected except your IP address.
Your participation is optional, and you may opt out anytime by accessing Settings (see Massive's FAQ for details).
Pressing Accept indicates that you agree to Massive's license and privacy policy.
```
#### 5. Start usage after consent
After receiving the user's consent, start usage using the `start()` method and created options:
```kotlin
// Check if there is user consent to use Massive and show the dialog if we need to request it.
if (!consentHelper.isConsentGiven()) {
consentHelper.showConsentDialog(
onAccept = {
// Start Massive if the user has given consent.
MassiveClient.start(massiveOptions) { result ->
result.onSuccess {
// Handle successful start.
}.onFailure { exception ->
// Handle start failure.
}
}
},
onDecline = {}
)
} else {
// If the user has already given consent, start Massive directly.
MassiveClient.start(massiveOptions) { result ->
result.onSuccess {
// Handle successful start.
}.onFailure { exception ->
// Handle start failure.
}
}
}
```
## Changes in the new Massive SDK 1.0
The new version of the Massive SDK introduces several significant changes aimed at improving usability, performance, and integration flexibility. Here is an overview of the key changes:
1. Dependency configuration: The dependency configuration process has been streamlined. Instead of manually setting up a local Maven repository, you can now directly add the Massive Maven repository to your project’s Gradle configuration. This simplification reduces setup time and potential errors, ensuring a more efficient integration of the SDK.
2. Changed package name: The name of the Massive SDK package has changed from `com.massive` to `com.joinmassive`.
3. Changed client interface: The `MassiveClient` has shifted from using a singleton instance to utilizing static methods. This change simplifies interaction with the SDK, making it more straightforward to initialize and manage the client throughout the application lifecycle.
4. Options handling: The process of providing options has been moved from the init stage to the `start` method. This allows for more dynamic configuration, enabling modification of the service options at the time of starting the client rather than during initialization. This separation ensures a quicker initialization process and more flexible configuration management.
5. Changed behavior of `stop`: The behavior of the stop method has been enhanced. In the new version, calling `stop` not only stops the usage but also shuts down the service entirely. This ensures that all operations are cleanly terminated and the service is properly shut down, providing a more robust mechanism for managing the SDK’s lifecycle.
6. Remote service: The Massive SDK service now runs as a separate process, enhancing the stability and performance of the main application.
### Migration from version 0.x
#### Dependency Configuration
* **Old Version**: Requires manually setting up a local Maven repository.
```bash
mkdir project/repo
unzip massive-sdk.zip -d project/repo
```
```gradle
repositories {
maven {
url = uri("/project/repo")
}
}
```
```gradle
dependencies {
implementation("com.massive:sdk:0.+")
}
```
* **New Version**: Directly add the Massive Maven repository to the dependency `repositories`.
```gradle
repositories {
maven {
url = uri("https://downloads.joinmassive.com/sdk/android/release")
}
}
```
```gradle
dependencies {
implementation("com.joinmassive:sdk:1.+")
}
```
#### Initialization
* **Old Version**:
```kotlin
MassiveClient.getInstance(context) { client ->
client.initAsync(MASSIVE_DEMO_API_TOKEN, massiveOptions, object : InitCallback {
override fun onSuccess() {
// Handle successful initialization.
}
override fun onFailure(message: String) {
// Handle initialization failure.
}
})
}
```
* **New Version**:
```kotlin
MassiveClient.init(API_TOKEN, context)
```
#### Start and stop methods
* **Old Version**:
```kotlin
client.start()
...
client.stop()
```
* **New Version**:
```kotlin
MassiveClient.start(massiveOptions) {
it.onSuccess { // Handle Started state. }
it.onFailure { // Handle error. }
}
...
MassiveClient.stop() {
it.onSuccess { // Handle Stopped state. }
it.onFailure { // Handle error. }
}
```
#### State handling
* **Old Version**:
```kotlin
// Async state handler.
client.listener = object : MassiveClientListener {
override fun onStateChange(newState: State) {
// Handle changed state.
}
}
...
// Current state.
client.state
```
* **New Version**:
```kotlin
// Handle state after the action.
MassiveClient.start(massiveOptions) {
it.onSuccess { // Handle Started state or query the current state. }
it.onFailure { // Handle error. }
}
// Current state.
when (MassiveClinet.state()) {
MassiveClient.State.Starting -> {
}
MassiveClient.State.Started -> {
}
MassiveClient.State.Stopped -> {
}
}
```
## Technical details
1. Android permissions
Massive SDK defines the following permissions in the manifest file:
* `android.permission.INTERNET`
* `android.permission.ACCESS_NETWORK_STATE`
* `android.permission.FOREGROUND_SERVICE`
* `android.permission.FOREGROUND_SERVICE_DATA_SYNC`
* `android.permission.WAKE_LOCK`
These permissions will be automatically added to your app during the build.
2. Client initialization
Interaction with the SDK always begins with initialization using `MassiveClient.init`, which requires your API token. This initialization step is crucial and should be performed only once during the application’s lifecycle. Subsequent calls to `init` will have no effect. Attempting to re-initialize the SDK with a different API token will result in a `MassiveReinitException`, ensuring that the SDK maintains a single consistent state throughout the app’s runtime.
Since the SDK consists of client and service components, initialization can trigger synchronization of their states. To handle this scenario and achieve accurate state tracking, you can pass an additional callback to the `init` method. This callback will be called in the main thread after synchronization is complete.
3. User consent before starting the usage
Before starting the usage for the first time (using the `start()` method), it is mandatory to obtain user consent for the terms of resource exchange. This aligns with user privacy and control principles. Ensure that your application includes a clear and understandable consent mechanism.
```kotlin
if (isUserConsentGiven) {
MassiveClient.start(massiveOptions) {}
}
```
4. Starting and stopping the client
Initialization of the `MassiveClient` with the `init()` method does not automatically launch the service or start the usage.
**It prepares the SDK for use but does not begin its operation.**
To ensure that the Massive is running, the `start()` method must be called after initialization and on each application relaunch. The `start()` method is designed to be idempotent, meaning it is safe to call multiple times. If the service is already started, subsequent calls to start will have no effect, preventing redundant operations.
The `stop()` method is used to stop and kill the service, effectively halting all operations and ensuring that the service is properly terminated. After calling `stop()`, you can restart the client by calling the `start()` method again, and it is possible to provide different options for the restart. This flexibility allows you to change the configuration or operational mode of the SDK as needed.
5. Client options and service types
Massive SDK can operate either as a *Background* or a *Foreground* service. The choice depends on your app's requirements and how you want to manage the SDK's resource usage.
* *Foreground Service*: Allow Massive to run more and less likely killed by the system but more visible with a customizable notification ensuring the user is aware of the service's operation.
**Running as a Foreground Service increases earning potential.**
* *Background Service:* Less intrusive, running silently without user interaction.
6. Customizing Foreground Service Notification
When running as a foreground service, Massive SDK allows customization of the notification displayed to the user.
You can set the title, text, and icon of the notification:
```kotlin
val options = MassiveOptions(
serviceType = MassiveServiceType.Foreground,
notificationOptions = MassiveNotificationOptions(
notificationTitle = "Your Title",
notificationText = "Your Text",
iconDrawable = R.drawable.your_icon
)
)
```
Massive library contains a pre-defined drawable icon resource `com.joinmassive.sdk.R.drawable.massive_sdk_icon`, but you can also provide your own.
7. Usage tracking
The Massive SDK includes functionality for tracking and retrieving current traffic usage statistics. This allows you to monitor the SDK's data usage, providing insights into its network activity.
The `usage` method in the `MassiveClient` class fetches and returns the current traffic usage in *bytes*. Please check the sample application for an example of how to use the method to retrieve and display the traffic usage statistics.
8. SDK remote service
The latest version of the Massive SDK uses a remote service that is launched as a separate process. This service handles the core operations of the SDK independently of the main application process, providing better performance and stability.
9. ProGuard rules
Massive SDK AAR embeds required Android ProGuard rules which are applied automatically if you are using the R8 compiler.
If you, however, don’t use R8 you have to apply the rules below:
consumer-rules.pro
```gradle
# Keep the public SDK entities
-keep class com.joinmassive.sdk.** { *; }
-keep interface com.joinmassive.sdk.** { *; }
-keep enum com.joinmassive.sdk.** { *; }
-dontwarn org.jetbrains.annotations.**
-keep class kotlin.Metadata { *; }
# Keep OkHttp3 and Moshi classes
-keep class com.squareup.okhttp3.** { *; }
-keep interface com.squareup.okhttp3.** { *; }
-keep class com.squareup.moshi.** { *; }
-keep interface com.squareup.moshi.** { *; }
-keepattributes Exceptions,InnerClasses,Signature,Deprecated,*Annotation*,EnclosingMethod
```
# Get usage
Source: https://docs.joinmassive.com/reporting-api-reference/get-usage
get /v1/usage
Get usage data for the given time range.
If no time range is provided, returns usage for the past 7 days (including today).
# Introduction
Source: https://docs.joinmassive.com/reporting-api-reference/reporting-api
This guide will help you get started with the Reporting API in just a few minutes.
# Getting started
We’ll use `curl` for our API call examples. You could also consider a dedicated tool for developing API requests (like [Postman](https://www.postman.com/)).
# Authenticate
The API key for the Reporting API is automatically enabled with access to the Residential Proxy.
```bash
curl --location 'https://api-network.joinmassive.com/reporting/v1/usage' \
--header 'Content-Type: application/json' \
--header 'x-api-key: {PROXY_PASSWORD}'
```
# Allocate traffic for an account
Source: https://docs.joinmassive.com/reseller-api-reference/allocate-traffic-for-an-account
post /accounts/{id}/allocations
# Create new account
Source: https://docs.joinmassive.com/reseller-api-reference/create-new-account
post /accounts
# Disable account
Source: https://docs.joinmassive.com/reseller-api-reference/disable-account
post /accounts/{id}/disable
# Enable account
Source: https://docs.joinmassive.com/reseller-api-reference/enable-account
post /accounts/{id}/enable
# Get account
Source: https://docs.joinmassive.com/reseller-api-reference/get-account
get /accounts/{id}
# Get account usage
Source: https://docs.joinmassive.com/reseller-api-reference/get-account-usage
get /accounts/{id}/usage
# Get list of existing accounts
Source: https://docs.joinmassive.com/reseller-api-reference/get-list-of-existing-accounts
get /accounts
# Get the allocation list
Source: https://docs.joinmassive.com/reseller-api-reference/get-the-allocation-list
get /accounts/{id}/allocations
Get the list of allocations made via the put endpoint for the account.
# Authentication
Source: https://docs.joinmassive.com/reseller-api-reference/reseller-api-authentication
The Proxy Resellers API uses API key authentication. You must include your API key in the header of every request to authenticate.
**Attention:** The API key for the Network API is not automatically enabled for this API. You must specifically request access to the Proxy Resellers API.
# Obtaining an API Key
To get an API key for the Proxy Resellers API:
1. Contact [Massive support](emailto:support@joinmassive.com) and request access to the Proxy Resellers API
2. Once approved, you will receive your API key
# Using Your API Key
Include your API key in the `x-api-key` header of all requests:
```http
x-api-key: {API_KEY}
```
**Example cURL request:**
```bash
curl --location 'https://api-network.joinmassive.com/resellers/accounts' \
--header 'Content-Type: application/json' \
--header 'x-api-key: {API_KEY}' \
--data '{
"username": "johndoe@example.com",
"password": "secretpassword"
}'
```
# Security Best Practices
* Keep your API key secure and don't share it publicly
* Use environment variables to store your API key in applications
* Rotate your API key periodically for enhanced security
If you believe your API key has been compromised, contact Massive support immediately for a replacement.
# Introduction
Source: https://docs.joinmassive.com/reseller-api-reference/reseller-api-introduction
The Proxy Resellers API allows you to manage proxy reseller accounts. With this API, you can create, update, and manage accounts that are used to authenticate with the Massive Network API.
# Key Features
* Create and update accounts
* Enable or disable accounts
* Allocate traffic for accounts
* Retrieve account usage information
* Get lists of accounts and allocations
# Getting Started
To start using the Proxy Resellers API, you'll need:
1. An API key (contact Massive support to enable it for this API)
2. Basic understanding of RESTful APIs and HTTP methods
Check out our [Quickstart Guide](#quickstart) to begin using the API in minutes.
# API Endpoints
The base URL for all API requests is:
[https://api-network.joinmassive.com/resellers](https://api-network.joinmassive.com/resellers)
For detailed information on available endpoints and operations, see our [API Reference](#api-reference).
# Authentication
All API requests must include your API key in the `x-api-key` header. Learn more in our [Authentication Guide](#authentication).
# Need Help?
If you have any questions or need assistance, please contact our support team at [support@joinmassive.com](mailto:support@joinmassive.com).
# Quickstart
Source: https://docs.joinmassive.com/reseller-api-reference/reseller-api-quickstart
This guide will help you get started with the Proxy Resellers API in just a few minutes.
# Prerequisites
* Your API key for the Proxy Resellers API
* cURL or any HTTP client (like Postman)
# Step 1: Verify Your API Key
First, let's check if your API key is working:
```bash
curl --location 'https://api-network.joinmassive.com/resellers/accounts' \
--header 'x-api-key: {API_KEY}'
```
If successful, you should receive a list of existing accounts or an empty array.
# Step 2: Create a New Account
Let's create a new reseller account:
```bash
curl --location 'https://api-network.joinmassive.com/resellers/accounts' \
--header 'Content-Type: application/json' \
--header 'x-api-key: {API_KEY}' \
--data '{
"username": "newreseller@example.com",
"password": "securepassword123",
"limit": 1000000
}'
```
If successful, you'll receive a response with the new account's ID.
# Step 3: Retrieve Account Details
Now, let's fetch the details of the account we just created:
```bash
curl --location 'https://api-network.joinmassive.com/resellers/accounts/{account_id}' \
--header 'x-api-key: {API_KEY}'
```
Replace {account_id} with the ID received in Step 2.
# Next Steps
You've now successfully created and retrieved an account using the Proxy Resellers API!
To learn more about available operations, check out our API Reference section.
# Update account
Source: https://docs.joinmassive.com/reseller-api-reference/update-account
put /accounts/{id}
# Accounting
Source: https://docs.joinmassive.com/residential/accounting
If you prefer to segregate requests for your customer invoicing or internal accounting, subaccounts can be provided.
| Key | Value | Examples |
| ---------- | --------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| subaccount | Any unique identifier of up to 255 characters (regardless of character encoding); Massive will bill requests made from subaccounts separately | [user@mail.com](mailto:user@mail.com), user1 |
Example:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-subaccount-customer@example.com:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
# ASN identifier targeting
Source: https://docs.joinmassive.com/residential/asn-type-targeting
You can target a request by an ASN number, a unique identification number that identifies a network or group of networks under a single routing policy on the internet.
| Key | Value |
| --- | ------------------------------------------------------------------------ |
| asn | ASN numbers are used by various routing protocols. Value range: 0-65536. |
Example using query parameters:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-asn-7018:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
This parameter can be used in combination with all other options. The following request targets by ASN in United States:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-country-US-asn-7018:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
# Authentication
Source: https://docs.joinmassive.com/residential/authentication
We support HTTPS, HTTP, and SOCKS5
**Attention:** Make sure to carefully check that your credentials and port number are correct for your auth type.
## HTTPS
How to authenticate using HTTPS.
| | |
| ---------- | ----- |
| HTTPS Port | 65535 |
```bash
curl --proxy https://network.joinmassive.com:65535 -U '{PROXY_USERNAME}:{API_KEY}' https://cloudflare.com/cdn-cgi/trace
```
## HTTP
How to authenticate using HTTP.
| | |
| --------- | ----- |
| HTTP Port | 65534 |
```bash
curl --proxy http://network.joinmassive.com:65534 -U '{PROXY_USERNAME}:{API_KEY}' https://cloudflare.com/cdn-cgi/trace
```
## SOCKS5
How to authenticate using SOCKS5.
| | |
| ----------- | ----- |
| SOCKS5 Port | 65533 |
```bash
curl -x socks5h://network.joinmassive.com:65533 -U '{PROXY_USERNAME}:{API_KEY}' https://www.cloudflare.com/cdn-cgi/trace
```
## Firewalled Ports
If port 65,535 is closed on your network, try port 1,080.
| | |
| ---- | ---- |
| Port | 1080 |
```bash
curl -x https://network.joinmassive.com:1080 -U '{PROXY_USERNAME}:{API_KEY}' https://cloudflare.com/cdn-cgi/trace
```
# Device-type targeting
Source: https://docs.joinmassive.com/residential/device-type-targeting
You can target different device types to execute the request on.
| Key | Value |
| ---- | ------------------------------------------------------------------------ |
| type | The type of device to target. Possible values: `mobile`, `common`, `tv`. |
**Supported Devices**
* `mobile` to execute request on mobile devices.
* `common` to execute request on any non-mobile device.
* `tv` to execute request on tv devices.
Example using query parameters:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-type-mobile-country-US:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
This parameter can be used in combination with all other options. The following request targets a mobile IP in New York State and assigns it a persistent session:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-type-mobile-country-US-subdivision-NY-session-1:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
# Domain Blocking
Source: https://docs.joinmassive.com/residential/domain-blocking
Control which domains can be accessed through your proxy connections with custom blocklists and exclusions.
## Overview
Domain blocking allows you to prevent specific domains from being accessed through your Massive proxy connections. This feature is useful for filtering out unwanted content like advertisements, tracking scripts, or malicious domains while browsing through the proxy.
## How Domain Blocking Works
When you make a request through the Massive proxy, the system checks the requested domain against multiple blocklists:
1. **Global blocklist** - Managed by Massive to block known malicious and problematic domains
2. **Your custom blocklist** - Domains you've requested to be blocked for your account
3. **Exclusion list** - Domains you've requested to be allowed, even if they're on the global blocklist
### Blocking Priority
The system follows this priority order:
1. **Your custom blocklist** (highest priority) - Always blocked
2. **Your exclusion list** - Allowed, even if globally blocked
3. **Global blocklist** - Blocked unless specifically excluded
## Account Hierarchy
Domain blocking works across your account structure:
* **Main account blocklist** - Applies to your main account.
* **Sub-account blocklist** - Applies only to specific sub-accounts
* **Exclusions** - Can be set at both the main account and sub-account levels
## Configuring Domain Blocking
### For Direct Proxy Accounts
To configure domain blocking for your standard proxy account, contact Massive support with:
1. **Domains to block** - List of domains you want blocked
2. **Domains to exclude** - List of domains to allow (bypass global blocklist)
3. **Account scope** - Whether blocking applies to main account, specific sub-accounts, or all
#### Example Request
```
Subject: Domain Blocking Configuration Request
Account: your-account-name
Domains to block:
- ads.example.com
- tracker.malicious.com
- unwanted-site.net
Domains to exclude from global blocklist:
- analytics.partner.com
- required-service.com
Scope: Main account and all sub-accounts
```
### For Reseller API Accounts (sub-accounts)
If you're using the Reseller API, domain blocking can be configured for accounts you create:
1. **Create the account** first using the [Reseller API](../reseller-api-reference/create-new-account)
2. **Request domain blocking** for that account through support
When requesting domain blocking for reseller accounts, include:
* The account ID or username created through the Reseller API
* Domains to block for that specific account
* Any exclusions needed
#### Example Reseller Request
```
Subject: Domain Blocking for Reseller Account
Reseller Account: your-reseller-account
Target Account: account-id-from-api (username: client@example.com)
Domains to block:
- social-media.com
- entertainment.net
Please configure domain blocking for the above reseller sub-account.
```
## What Happens When Domains Are Blocked
When a blocked domain is accessed through the proxy:
* **HTTP CONNECT request to proxy**: Return a `452` error with the message "The domain is blocked by Massive content policy"
* **HTTP/HTTPS requests**: Connection is refused
* **The connection is closed** to prevent further requests
## Domain Matching
Domain matching is exact - subdomains are treated separately:
* Blocking `example.com` only blocks `example.com`
* To block `subdomain.example.com`, it must be specified separately
* To block all subdomains, each must be listed individually
### Examples
| Blocked Domain | What's Blocked | What's Still Allowed |
| -------------- | ------------------ | ------------------------------------ |
| `ads.com` | `ads.com` only | `sub.ads.com`, `my-ads.com` |
| `tracker.net` | `tracker.net` only | `api.tracker.net`, `tracker.network` |
## Common Use Cases
### Content Filtering
Block access to inappropriate or distracting websites for corporate environments.
### Ad Blocking
Prevent advertising domains from loading to improve browsing speed and reduce bandwidth usage.
### Security Enhancement
Block known malicious domains to protect against phishing and malware.
### Compliance
Meet regulatory requirements by blocking access to restricted content categories.
## Testing Your Configuration
After your domain blocking is configured, you can test it:
```bash
# Test a blocked domain (should return error)
curl -x your-proxy-endpoint "http://blocked-domain.com"
# Test an allowed domain (should work normally)
curl -x your-proxy-endpoint "http://allowed-domain.com"
```
## Self-Service Configuration (Coming Soon)
We're working on a dashboard where you'll be able to:
* Add and remove domains from your blocklist instantly
* Manage exclusions in real-time
* Configure different rules for sub-accounts
* View blocking activity and statistics
Until then, please contact support for all domain blocking configuration requests.
## Best Practices
1. **Start small** - Begin with a few critical domains and expand as needed
2. **Test thoroughly** - Verify your configuration doesn't block legitimate services
3. **Document your rules** - Keep track of why specific domains are blocked
4. **Regular reviews** - Periodically review your blocklist for outdated entries
5. **Monitor usage** - Watch for unexpected blocking that might impact your operations
## Support
To request the domain blocking configuration:
**Submit a support request**: [Massive Support Form](https://forms.fillout.com/t/p8dRqBYs58us)
**Response time**: Configuration changes are typically processed within 24 hours\
**Emergency requests**: Critical security blocks can be prioritized
**For direct proxy accounts**: include your account name, specific domains, and desired scope in your support request.
**For reseller accounts**: include your reseller account details, the target account ID/username, and the domains to configure.
> **Note**: Domain blocking for reseller accounts requires the target account to be created through the Reseller API first. Contact support if you need clarification on the process for your specific use case.
# Error Types
Source: https://docs.joinmassive.com/residential/error-types
Massive may respond with one of several common or custom error messages:
| Status code | Reason phrase | Additional comments |
| ----------- | ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `400` | Bad Request | Your request was malformed, most likely because of invalid routing parameters; see the response body for human-readable details |
| `407` | Proxy Authentication Required | Your login email address, Massive API token, or both were incorrect |
| `452` | Disallowed Content | The protocol, port, or content that you requested conflicts with Massive’s content policy; see the Link header for the entire policy |
| `500` | Internal server error | Something went wrong on the serverside |
| `502` | Bad gateway | Massive was unable to find an appropriate node |
| `503` | Service Unavailable | Massive was unable to satisfy the geotargeting specifications or other elements of your request; or Massive network experiences high demand; see the response body for human-readable details |
# Geotargeting
Source: https://docs.joinmassive.com/residential/geotargeting
You can tune the request by providing geo parameters like an [ISO ZIP code, subdivision, and country code](https://www.iso.org/obp/ui/#search), and by [city](https://www.geonames.org/).
You can tune the request by providing geo parameters like an [ISO ZIP code, subdivision, and country code](https://www.iso.org/obp/ui/#search), and by [city](https://www.geonames.org/).
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-country-US-zipcode-10001:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
## Country, subdivision, city, zipcode
| Key | Value | Examples |
| ----------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------- |
| country | A two-letter country code (these codes are case insensitive) | US, GB |
| subdivision | The alphanumeric second part (proceeding the separator) of a first-level subdivision code in the (prerequisite) country (case insensitive) | CA, LND |
| city | A commonly spelled city name (temporarily case sensitive and inclusive of URL-encoded spaces and punctuation marks) in the (prerequisite) country. We always use the English (en) variant of the city name, which can be verified on [GeoNames](https://www.geonames.org/) (as referenced in [MaxMind’s documentation](https://support.maxmind.com/hc/en-us/articles/4414877149467-IP-Geolocation-Data#h_01FRRNFD5Z5EWNCAXM6SZZ5H2C)). | New York, London |
| zipcode | A postal code. Please take a look at the limitations below. | 10001, OX2 |
## Geotargeting rules
* `country` key must always persist if any of the geo parameters is specified. Otherwise, HTTP 400 is returned.
* If more than one geo key is specified, the server finds an appropriate node strictly matching all the parameters. The only exception is `zipcode`: if specified, `city` key is ignored.
* **Details**:
* If both subdivision and zipcode are provided, the city is ignored.
* If both zipcode and city are provided, the city is ignored.
* If subdivision and city are provided, both are strictly matched.
*Please, take into account, that due to technical reasons, the more strict geotargeting narrows the range of appropriate nodes.*
## Zipcode Notes
For the following countries, we accept partial postal codes with the number of characters indicated below:
* **United States**: 5
* **Canada**: 3
* **United Kingdom**: 2-4
* **Brazil**: 5
* **Ireland**: 3
* **Japan**: 7 (specified for the first 6. The last digit defaults to 1)
* **Netherlands**: 4
* **Portugal**: 7 (accurate for the first 4. The last 3 often default to -001)
* **Singapore**: 2
Geotargeting by country and city is always more robust than by ZIP code.
## Examples
### Country
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-country-US:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
### Country and city
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-country-US-city-New%20York:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
### Country and subdivision
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-country-US-subdivision-NY:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
### Country and zipcode
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-country-US-zipcode-10001:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
# Introduction
Source: https://docs.joinmassive.com/residential/introduction
The Massive Network is a global edge network that’s used by partners to monitor internet performance, gather business intelligence, and detect fraud and malware.
## About us
The network includes more than 1,000,000 residential computers and devices in more than 195 countries around the world. 100% of these computers and devices have been explicitly opted in by users through the [Massive SDK](https://www.joinmassive.com/getpaid) for app developers, which is designed to maintain user-friendly limits on processing, storage, and bandwidth usage.
## Getting started
The first step to using Massive Network is making sure your credentials work with a simple curl request.
Test your credentials in shell.
Dive right in to all connect methods: HTTPS, HTTP, & SOCKS5.
# Quickstart
Source: https://docs.joinmassive.com/residential/quickstart
Start crawling the web in under 5 minutes.
## Test your credentials
If you already have an account with Massive, get started by using the [proxy request generator](https://partners.joinmassive.com/quickstart) in our developer portal.

To generate your requests manually, continue following our documentation.
## Configure your environment
Make sure your credentials work and that you use the correct port configuration.
| | |
| :---------: | :--------------: |
| Username | `PROXY_USERNAME` |
| API Key | `API_KEY` |
| HTTPS Port | 65535 |
| HTTP Port | 65534 |
| SOCKS5 Port | 65533 |
## Check credentials
Make sure your API key works with this simple shell script.
**Attention:** If you credentials do not appear below, they may not be provisioned. Sign up for an account or email [support@joinmassive.com](support@joinmassive.com).
```bash
curl --proxy https://network.joinmassive.com:65535 --proxy-user 'PROXY_USERNAME:API_KEY' https://cloudflare.com/cdn-cgi/trace
```
# Request routing
Source: https://docs.joinmassive.com/residential/routing
Our robust proxy services allows for geotargeting, sticky sessions, device type targeting, and advanced accounting and reporting.
Massive accepts extended user IDs that let you add targeting specifications to requests. Append a standard URL query string with routing parameters to your proxy username. You can combine routing parameters in any order.
## Standard syntax
Our proxy protocol uses `-` syntax to append routing parameters, which will used throughout our documentation.
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-country-US-zipcode-10001:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
## Alternative syntax
The alternative syntax `?` + `=` + `&` is also supported.
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}?country=US&zipcode=10001:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
# .NET (in C#)
Source: https://docs.joinmassive.com/residential/samples/.net
.NET integrations should connect to the [Massive Network’s HTTP port](/authentication#HTTP) `65534` because [.NET doesn’t broadly support HTTPS proxies yet](https://github.com/dotnet/runtime/pull/87638):
```csharp
using System.Net;
class Demo {
static async Task Main(string[] args) {
string username = Uri.EscapeDataString("{PROXY_USERNAME}");
string password = "{API_Key}";
string url = "https://cloudflare.com/cdn-cgi/trace"; // Insert your target URL here
string proxy = "http://network.joinmassive.com:65534";
HttpClientHandler handler = new() {
Proxy = new WebProxy(proxy),
DefaultProxyCredentials = new NetworkCredential(
username, password
)
};
HttpClient client = new(handler);
HttpResponseMessage response = await client.GetAsync(url);
Console.WriteLine(await response.Content.ReadAsStringAsync());
}
}
```
# FoxyProxy
Source: https://docs.joinmassive.com/residential/samples/foxyproxy
How to update proxy settings in your browser
### Quick Fix: Proxy Settings Not Updating in Your Browser?
When modifying proxy settings in browser-based proxy management tools such as **SwitchyOmega** or **FoxyProxy**, you may encounter an issue where your browser continues to use the old configuration, even after saving the new settings.
This often happens when switching locations, adjusting sticky sessions, or updating other proxy options.
Fortunately, this is a common issue and can be easily resolved with a simple fix.
💡 Here’s what you need to do:
1. Open **SwitchyOmega** or **FoxyProxy**.
2. Update your proxy settings to your desired configuration.
3. Save the changes to apply them.
4. **Restart your browser** — this step is crucial as it clears the cached settings and ensures the browser uses the updated proxy.
5. Double-check your new settings using any IP lookup site.
This process applies to all browser-based proxy managers, not just specific tools. No complex fixes are required; a simple browser restart does the trick.
# Puppeteer
Source: https://docs.joinmassive.com/residential/samples/puppeteer
Integrate the Massive Network into your Puppeteer workflows by setting the `--proxy-server` launch flag then calling a page object’s `authenticate` method:
```javascript
#!/usr/bin/env node
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
args: ['--proxy-server=https://network.joinmassive.com:65535']
});
const page = (await browser.pages())[0];
await page.authenticate({
username: '{PROXY_USERNAME},
password: '{API_KEY}'
});
await page.goto('https://cloudflare.com/cdn-cgi/trace'); // Insert your target URL here
console.log(await page.content());
browser.close();
})();
```
# (Vanilla) Python
Source: https://docs.joinmassive.com/residential/samples/python
To connect to the Massive Network from Python, include your encoded credentials in the proxy address (this usage doesn’t risk leaking your API token to a shared history file per the caveat for Curl):
```javascript
#!/usr/bin/env python3
import requests
import urllib
username = '{PROXY_USERNAME}'
password = '{API_KEY}'
url = 'https://cloudflare.com/cdn-cgi/trace' # Insert your target URL here
host = 'network.joinmassive.com'
port = 65535
proxy = f'https://{username}:{password}@{host}:{port}'
response = requests.get(url, proxies={'http': proxy, 'https': proxy})
print(response.content)
```
# Ruby
Source: https://docs.joinmassive.com/residential/samples/ruby
Ruby’s standard HTTP library doesn’t seem to support HTTPS proxy connections, so connect to the [Massive Network’s HTTP port](/authentication#http) with Ruby:
```javascript
#!/usr/bin/env node
const puppeteer = require('puppeteer');
(async () => {
const browser = await puppeteer.launch({
args: ['--proxy-server=https://network.joinmassive.com:65535']
});
const page = (await browser.pages())[0];
await page.authenticate({
username: '{PROXY_USERNAME},
password: '{API_KEY}'
});
await page.goto('https://cloudflare.com/cdn-cgi/trace'); // Insert your target URL here
console.log(await page.content());
browser.close();
})();
```
# Scrapy (for Python)
Source: https://docs.joinmassive.com/residential/samples/scrapy
After installing Scrapy (`pip install scrapy`) and creating a project (`scrapy startproject [project name]`), you can connect to the Massive Network by saving code like that below to a file in the new `[project name]/[project name]/spiders` subdirectory then running `scrapy crawl demo` from the top-level `[project name]` directory (Scrapy doesn’t seem to support HTTPS proxy connections, but you can use the [network’s HTTP port](/authentication#http)):
```python
import scrapy
import urllib
class Demo(scrapy.Spider):
name = 'demo'
def parse(self, response):
print(response.body)
def start_requests(self):
username = '{PROXY_USERNAME}'
password = '{API_KEY}'
url = 'https://cloudflare.com/cdn-cgi/trace' # Insert your target URL here
host = 'network.joinmassive.com'
port = 65534
proxy = f'http://{username}:{password}@{host}:{port}'
yield scrapy.Request(url, callback=self.parse, meta={'proxy': proxy})
```
# SwitchyOmega
Source: https://docs.joinmassive.com/residential/samples/switchyomega
How to update proxy settings in your browser
### Quick Fix: Proxy Settings Not Updating in Your Browser?
When modifying proxy settings in browser-based proxy management tools such as **SwitchyOmega** or **FoxyProxy**, you may encounter an issue where your browser continues to use the old configuration, even after saving the new settings.
This often happens when switching locations, adjusting sticky sessions, or updating other proxy options.
Fortunately, this is a common issue and can be easily resolved with a simple fix.
💡 Here’s what you need to do:
1. Open **SwitchyOmega** or **FoxyProxy**.
2. Update your proxy settings to your desired configuration.
3. Save the changes to apply them.
4. **Restart your browser** — this step is crucial as it clears the cached settings and ensures the browser uses the updated proxy.
5. Double-check your new settings using any IP lookup site.
This process applies to all browser-based proxy managers, not just specific tools. No complex fixes are required; a simple browser restart does the trick.
# Sticky sessions
Source: https://docs.joinmassive.com/residential/sticky-sessions
We support session persistence (AKA sticky sessions) with a customizable TTL, defaulting to 15 minutes.
## Using sticky sessions
| Key | Value | TTL | Examples |
| ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ---------------------------------------------------- | ---------------- |
| session | Any unique identifier of up to 255 characters (regardless of character encoding); Massive will make best efforts to route requests in the same session to the same egress node | Default: 15 minutes (customizable with `sessionttl`) | session42, 1234 |
| sessionttl | Customizable session TTL in minutes, up to 240 minutes | Default: 15 minutes | 30, 60, 120, 240 |
You can inject a session identifier, like a unique representation of your app or active task, to specify that multiple requests should originate from a single egress node (if available):
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-session-37:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
### Session TTL Behavior
* Session TTL defaults to 15 minutes but can be customized using the `sessionttl` parameter up to 240 minutes (4 hours).
* **Important**: Sessions use static TTL - they expire at creation time + TTL and are not extended by subsequent requests.
* For example, to set the TTL to 30 minutes:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-session-37-sessionttl-30:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
### Session Rotation
When a session identifier is specified and found, the server will perform a request via the same node unless:
* TTL is expired (sessions expire exactly at creation time + TTL)
* The request limit per minute for the node is exceeded
* The node has gone offline
* Error limit is reached (in flex mode)
If the session identifier is not found or the conditions above are not met, a new session is created with the specified ID and attached to a new node.
## Session Modes
| Key | Value | Description |
| ----------- | ---------------- | ----------------------------------- |
| sessionmode | `strict`, `flex` | Controls session behavior on errors |
### Flex Mode (Default)
By default, sessions operate in **flex mode** where sessions persist through errors up to a configurable limit. In this mode:
* Sessions continue through errors up to the error limit (default: 15)
* Error count resets to 0 on successful requests
* Provides better IP stability during transient failures
* May retry failing nodes multiple times
**Note:** The default error limit is 15. After 15 consecutive errors, a new node is assigned to the sticky session. You can customize this with the `sessionerr` parameter.
Example of using undefined `sessionmode`, which defaults to `sessionmode-flex`:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-session-123:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
Example with `sessionmode-flex` explicitly defined:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-session-123-sessionmode-flex:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
### Strict Mode
Sessions can operate in **strict mode** where any error immediately invalidates the session and triggers rotation to a new node. This ensures clean IP rotation on failures but may change IPs more frequently.
Example with `sessionmode-strict`:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-session-123-sessionmode-strict:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
## Additional Parameters
| Key | Value | Description | Default |
| ---------- | -------------- | ------------------------------------------------------- | ------- |
| sessionerr | Number (1-100) | Maximum consecutive errors before rotation in flex mode | 15 |
### Customizing Error Limit
In flex mode, you can customize how many errors are allowed before rotation:
```bash
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-session-123-sessionmode-flex-sessionerr-5:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
This example allows up to 5 consecutive errors before rotating to a new node.
## Best Practices
1. **Plan TTL appropriately**: Since sessions use static TTL (not extended by activity), set an appropriate duration for your use case
2. **Choose the right mode**: Default flex mode provides IP stability; use strict mode if you need immediate rotation on any error
3. **Monitor error rates**: Adjust `sessionerr` based on your tolerance for retries (default is 15)
4. **Session ID naming**: Use descriptive session IDs to help with debugging and monitoring
### Parameters Applied at Session Creation/Rotation Only
The following parameters are only applied when a session is created or rotated, not on existing sessions:
* `sessionttl` - TTL duration
* `sessionmode` - Strict vs flex behavior
* `sessionerr` - Error limit for flex mode
* Geographic parameters (`subdivision`, `zipcode`, etc.)
This means changing these parameters on subsequent requests with the same session ID will have no effect until the session rotates to a new node.
### Session-Breaking Parameters
**Critical**: Changing `country` or `city` parameters creates a NEW session with a different identity, breaking session continuity. These are part of the session token itself.
Unlike other parameters that are ignored until rotation, `country` and `city` are part of the session's unique identifier. Changing them creates an entirely different session:
```bash
# First request creates session with US/NewYork
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-session-test-country-US-city-NewYork:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
# This creates a DIFFERENT session - not the same as above!
curl -x https://network.joinmassive.com:65535 \
-U '{PROXY_USERNAME}-session-test-country-US-city-LosAngeles:{API_KEY}' \
https://cloudflare.com/cdn-cgi/trace
```
### Parameters Always Processed
Some parameters are processed on every request regardless of session state:
* `subaccount` - For billing and tracking
* `httpredirect` - For HTTP to HTTPS redirect behavior
These parameters take effect immediately on each request.
# Usage Alerts
Source: https://docs.joinmassive.com/residential/usage-alerts
How to set up usage alerts on the [partners](https://partners.joinmassive.com) page
Usage alerts help you stay informed when your usage reaches a certain threshold.
You can set up alerts to receive notifications via email, ensuring you never exceed
your desired limits. Follow these simple steps to configure and manage your alerts.
**Note**:
* Alerts work only with **residential proxies**.
* Alerts apply **within a single billing cycle**. For example, if you set an alert for 10GB, use 9GB, and your plan renews, using 1GB more in the new cycle will not trigger the previous alert.
* Alerts are processed asynchronously, so they may trigger with a slight delay after requests to Massive Proxy are made
* You can create up to **10 alerts per account**. If you need more, please contact our team.
## Create a New Alert
1. Go to the [Alerts](https://partners.joinmassive.com/residential/alerts) tab and click **Create New Alert**

2. Fill in the alert details:

where
* **Threshold**: Set the GB value that triggers an alert.
* **Emails**: Add recipients for the alert (default is your registration email).
* **Enable**: Toggle to activate the alert after creation (default to enabled).
Example:

3. Click **Save** to activate the alert.
## Manage Existing Alerts
4. Use the **Actions** column to edit, disable, or remove alerts:

## Example Alert Email
As a result, you should receive the following email in your inbox:

With the following content:

# Usage restrictions
Source: https://docs.joinmassive.com/residential/usage-restrictions
Some restrictions apply to the use of both the HTTP(S) and SOCKS5 endpoints.
# General Restrictions
* UDP communication isn’t allowed.
* Ports other than the standard `80` and `443` are blocked; `http://example.com/` and `https://example.com/` are acceptable targets, for example, but `http://example.com:8080` would be rejected.
* The Massive Network is intended to optimize delivery of content that could be reasonably considered “family friendly” to a (currently) worldwide userbase (in the future, regional distinctions are planned), so potentially dangerous or offensive content isn’t allowed.
A request that’s blocked due to any of these protocol, port, or content restrictions will fail with a `452` Disallowed Content error message.
# Restricted Domains
* We restrict access to content that is generally used to evade the law or site TOS policies. If you are getting blocked from accessing certain content that you have a legitimate reason to access, then contact support to complete our KYC process to gain access.
# Port 25
* `Port 25` cannot be opened on our residential proxy network. If you want to use residential proxies to test email sending, you can request access for `Port 587` or `Port 465`.
# Request access
[Contact support](https://joinmassive.atlassian.net/servicedesk/customer/portal/2/group/2/create/13) if you have questions about our policies or want to complete KYC to gain access to content that is restricted by default.