curl --request POST \
--url https://api.revenuebase.ai/v2/contact/exports/estimate \
--header 'Content-Type: application/json' \
--header 'X-Key: <api-key>' \
--data '
{
"filter": {
"type": "group",
"op": "AND",
"children": [
{
"type": "condition",
"column": "COUNTRY_NAME_PER",
"operator": "eq",
"value": "United States"
},
{
"type": "condition",
"column": "JOB_LEVEL_PER",
"operator": "eq",
"value": "VP"
}
]
},
"columns": [
"FULL_NAME_PER",
"JOB_TITLE_PER",
"COMPANY_NAME_ORG",
"EMAIL_ADDRESS_PER"
],
"maxRows": 100,
"reveal": [
"email"
],
"format": "csv",
"compression": "gz"
}
'import requests
url = "https://api.revenuebase.ai/v2/contact/exports/estimate"
payload = {
"filter": {
"type": "group",
"op": "AND",
"children": [
{
"type": "condition",
"column": "COUNTRY_NAME_PER",
"operator": "eq",
"value": "United States"
},
{
"type": "condition",
"column": "JOB_LEVEL_PER",
"operator": "eq",
"value": "VP"
}
]
},
"columns": ["FULL_NAME_PER", "JOB_TITLE_PER", "COMPANY_NAME_ORG", "EMAIL_ADDRESS_PER"],
"maxRows": 100,
"reveal": ["email"],
"format": "csv",
"compression": "gz"
}
headers = {
"X-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
filter: {
type: 'group',
op: 'AND',
children: [
{
type: 'condition',
column: 'COUNTRY_NAME_PER',
operator: 'eq',
value: 'United States'
},
{type: 'condition', column: 'JOB_LEVEL_PER', operator: 'eq', value: 'VP'}
]
},
columns: ['FULL_NAME_PER', 'JOB_TITLE_PER', 'COMPANY_NAME_ORG', 'EMAIL_ADDRESS_PER'],
maxRows: 100,
reveal: ['email'],
format: 'csv',
compression: 'gz'
})
};
fetch('https://api.revenuebase.ai/v2/contact/exports/estimate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.revenuebase.ai/v2/contact/exports/estimate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'filter' => [
'type' => 'group',
'op' => 'AND',
'children' => [
[
'type' => 'condition',
'column' => 'COUNTRY_NAME_PER',
'operator' => 'eq',
'value' => 'United States'
],
[
'type' => 'condition',
'column' => 'JOB_LEVEL_PER',
'operator' => 'eq',
'value' => 'VP'
]
]
],
'columns' => [
'FULL_NAME_PER',
'JOB_TITLE_PER',
'COMPANY_NAME_ORG',
'EMAIL_ADDRESS_PER'
],
'maxRows' => 100,
'reveal' => [
'email'
],
'format' => 'csv',
'compression' => 'gz'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.revenuebase.ai/v2/contact/exports/estimate"
payload := strings.NewReader("{\n \"filter\": {\n \"type\": \"group\",\n \"op\": \"AND\",\n \"children\": [\n {\n \"type\": \"condition\",\n \"column\": \"COUNTRY_NAME_PER\",\n \"operator\": \"eq\",\n \"value\": \"United States\"\n },\n {\n \"type\": \"condition\",\n \"column\": \"JOB_LEVEL_PER\",\n \"operator\": \"eq\",\n \"value\": \"VP\"\n }\n ]\n },\n \"columns\": [\n \"FULL_NAME_PER\",\n \"JOB_TITLE_PER\",\n \"COMPANY_NAME_ORG\",\n \"EMAIL_ADDRESS_PER\"\n ],\n \"maxRows\": 100,\n \"reveal\": [\n \"email\"\n ],\n \"format\": \"csv\",\n \"compression\": \"gz\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.revenuebase.ai/v2/contact/exports/estimate")
.header("X-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"filter\": {\n \"type\": \"group\",\n \"op\": \"AND\",\n \"children\": [\n {\n \"type\": \"condition\",\n \"column\": \"COUNTRY_NAME_PER\",\n \"operator\": \"eq\",\n \"value\": \"United States\"\n },\n {\n \"type\": \"condition\",\n \"column\": \"JOB_LEVEL_PER\",\n \"operator\": \"eq\",\n \"value\": \"VP\"\n }\n ]\n },\n \"columns\": [\n \"FULL_NAME_PER\",\n \"JOB_TITLE_PER\",\n \"COMPANY_NAME_ORG\",\n \"EMAIL_ADDRESS_PER\"\n ],\n \"maxRows\": 100,\n \"reveal\": [\n \"email\"\n ],\n \"format\": \"csv\",\n \"compression\": \"gz\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.revenuebase.ai/v2/contact/exports/estimate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"filter\": {\n \"type\": \"group\",\n \"op\": \"AND\",\n \"children\": [\n {\n \"type\": \"condition\",\n \"column\": \"COUNTRY_NAME_PER\",\n \"operator\": \"eq\",\n \"value\": \"United States\"\n },\n {\n \"type\": \"condition\",\n \"column\": \"JOB_LEVEL_PER\",\n \"operator\": \"eq\",\n \"value\": \"VP\"\n }\n ]\n },\n \"columns\": [\n \"FULL_NAME_PER\",\n \"JOB_TITLE_PER\",\n \"COMPANY_NAME_ORG\",\n \"EMAIL_ADDRESS_PER\"\n ],\n \"maxRows\": 100,\n \"reveal\": [\n \"email\"\n ],\n \"format\": \"csv\",\n \"compression\": \"gz\"\n}"
response = http.request(request)
puts response.read_body{
"creditsEstimate": 200
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Estimate export cost
Compare export choices and forecast the cost before starting a download job.
curl --request POST \
--url https://api.revenuebase.ai/v2/contact/exports/estimate \
--header 'Content-Type: application/json' \
--header 'X-Key: <api-key>' \
--data '
{
"filter": {
"type": "group",
"op": "AND",
"children": [
{
"type": "condition",
"column": "COUNTRY_NAME_PER",
"operator": "eq",
"value": "United States"
},
{
"type": "condition",
"column": "JOB_LEVEL_PER",
"operator": "eq",
"value": "VP"
}
]
},
"columns": [
"FULL_NAME_PER",
"JOB_TITLE_PER",
"COMPANY_NAME_ORG",
"EMAIL_ADDRESS_PER"
],
"maxRows": 100,
"reveal": [
"email"
],
"format": "csv",
"compression": "gz"
}
'import requests
url = "https://api.revenuebase.ai/v2/contact/exports/estimate"
payload = {
"filter": {
"type": "group",
"op": "AND",
"children": [
{
"type": "condition",
"column": "COUNTRY_NAME_PER",
"operator": "eq",
"value": "United States"
},
{
"type": "condition",
"column": "JOB_LEVEL_PER",
"operator": "eq",
"value": "VP"
}
]
},
"columns": ["FULL_NAME_PER", "JOB_TITLE_PER", "COMPANY_NAME_ORG", "EMAIL_ADDRESS_PER"],
"maxRows": 100,
"reveal": ["email"],
"format": "csv",
"compression": "gz"
}
headers = {
"X-Key": "<api-key>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {'X-Key': '<api-key>', 'Content-Type': 'application/json'},
body: JSON.stringify({
filter: {
type: 'group',
op: 'AND',
children: [
{
type: 'condition',
column: 'COUNTRY_NAME_PER',
operator: 'eq',
value: 'United States'
},
{type: 'condition', column: 'JOB_LEVEL_PER', operator: 'eq', value: 'VP'}
]
},
columns: ['FULL_NAME_PER', 'JOB_TITLE_PER', 'COMPANY_NAME_ORG', 'EMAIL_ADDRESS_PER'],
maxRows: 100,
reveal: ['email'],
format: 'csv',
compression: 'gz'
})
};
fetch('https://api.revenuebase.ai/v2/contact/exports/estimate', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.revenuebase.ai/v2/contact/exports/estimate",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'filter' => [
'type' => 'group',
'op' => 'AND',
'children' => [
[
'type' => 'condition',
'column' => 'COUNTRY_NAME_PER',
'operator' => 'eq',
'value' => 'United States'
],
[
'type' => 'condition',
'column' => 'JOB_LEVEL_PER',
'operator' => 'eq',
'value' => 'VP'
]
]
],
'columns' => [
'FULL_NAME_PER',
'JOB_TITLE_PER',
'COMPANY_NAME_ORG',
'EMAIL_ADDRESS_PER'
],
'maxRows' => 100,
'reveal' => [
'email'
],
'format' => 'csv',
'compression' => 'gz'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"X-Key: <api-key>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.revenuebase.ai/v2/contact/exports/estimate"
payload := strings.NewReader("{\n \"filter\": {\n \"type\": \"group\",\n \"op\": \"AND\",\n \"children\": [\n {\n \"type\": \"condition\",\n \"column\": \"COUNTRY_NAME_PER\",\n \"operator\": \"eq\",\n \"value\": \"United States\"\n },\n {\n \"type\": \"condition\",\n \"column\": \"JOB_LEVEL_PER\",\n \"operator\": \"eq\",\n \"value\": \"VP\"\n }\n ]\n },\n \"columns\": [\n \"FULL_NAME_PER\",\n \"JOB_TITLE_PER\",\n \"COMPANY_NAME_ORG\",\n \"EMAIL_ADDRESS_PER\"\n ],\n \"maxRows\": 100,\n \"reveal\": [\n \"email\"\n ],\n \"format\": \"csv\",\n \"compression\": \"gz\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("X-Key", "<api-key>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.revenuebase.ai/v2/contact/exports/estimate")
.header("X-Key", "<api-key>")
.header("Content-Type", "application/json")
.body("{\n \"filter\": {\n \"type\": \"group\",\n \"op\": \"AND\",\n \"children\": [\n {\n \"type\": \"condition\",\n \"column\": \"COUNTRY_NAME_PER\",\n \"operator\": \"eq\",\n \"value\": \"United States\"\n },\n {\n \"type\": \"condition\",\n \"column\": \"JOB_LEVEL_PER\",\n \"operator\": \"eq\",\n \"value\": \"VP\"\n }\n ]\n },\n \"columns\": [\n \"FULL_NAME_PER\",\n \"JOB_TITLE_PER\",\n \"COMPANY_NAME_ORG\",\n \"EMAIL_ADDRESS_PER\"\n ],\n \"maxRows\": 100,\n \"reveal\": [\n \"email\"\n ],\n \"format\": \"csv\",\n \"compression\": \"gz\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.revenuebase.ai/v2/contact/exports/estimate")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["X-Key"] = '<api-key>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"filter\": {\n \"type\": \"group\",\n \"op\": \"AND\",\n \"children\": [\n {\n \"type\": \"condition\",\n \"column\": \"COUNTRY_NAME_PER\",\n \"operator\": \"eq\",\n \"value\": \"United States\"\n },\n {\n \"type\": \"condition\",\n \"column\": \"JOB_LEVEL_PER\",\n \"operator\": \"eq\",\n \"value\": \"VP\"\n }\n ]\n },\n \"columns\": [\n \"FULL_NAME_PER\",\n \"JOB_TITLE_PER\",\n \"COMPANY_NAME_ORG\",\n \"EMAIL_ADDRESS_PER\"\n ],\n \"maxRows\": 100,\n \"reveal\": [\n \"email\"\n ],\n \"format\": \"csv\",\n \"compression\": \"gz\"\n}"
response = http.request(request)
puts response.read_body{
"creditsEstimate": 200
}{
"detail": [
{
"loc": [
"<string>"
],
"msg": "<string>",
"type": "<string>",
"input": "<unknown>",
"ctx": {}
}
]
}Credits and plans
PAYG is Pay-as-you-go. AYCE is All-you-can-eat.| Usage | PAYG | AYCE |
|---|---|---|
| Estimate request | Free 0 credits | Included 0 credits |
reveal choices you plan to send to Export.
Choose what to retrieve
SetmaxRows to the number of contacts you want. Use reveal to
choose which contact details you retrieve; columns controls which fields
appear in the file.
Export reveal | PAYG: credits per row | AYCE |
|---|---|---|
[] | 1 for the contact profile | Unlimited 0 credits |
["email"] | 1 for the row, +1 for a populated email | Unlimited 0 credits |
["mobile"] | 1 for the row, +10 for a populated mobile | Unlimited 0 credits |
["email", "mobile"] | 1 for the row, +1 for a populated email, +10 for a populated mobile | Unlimited 0 credits |
- PAYG exports add 10 credits per SmartSearch filter node, once per request. This means each semantic or lookalike node; ordinary field conditions add no search fee.
- SmartSearch adds 0 credits on AYCE and is free on Count and View on both plans.
- Per-request and rate limits apply to both plans, including unlimited AYCE retrieval.
reveal, or sending null, selects both email and mobile.
Removing those fields from columns does not remove their reveal charges.
Set reveal explicitly to control the cost.Example: estimate 100 contacts with email
Set your API key asREVENUEBASE_API_KEY. This reuses the Count/View
audience, caps the export at 100 rows, and excludes mobile charges.
curl --request POST 'https://api.revenuebase.ai/v2/contact/exports/estimate' \
--header "X-Key: $REVENUEBASE_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"filter": {
"type": "group",
"op": "AND",
"children": [
{
"type": "condition",
"column": "COUNTRY_NAME_PER",
"operator": "eq",
"value": "United States"
},
{
"type": "condition",
"column": "JOB_LEVEL_PER",
"operator": "eq",
"value": "VP"
}
]
},
"columns": [
"FULL_NAME_PER",
"JOB_TITLE_PER",
"COMPANY_NAME_ORG",
"EMAIL_ADDRESS_PER"
],
"maxRows": 100,
"reveal": [
"email"
],
"format": "csv",
"compression": "gz"
}'
{
"creditsEstimate": 200
}
{ "creditsEstimate": null }
| Field | What it means |
|---|---|
creditsEstimate as a number | Forecast credits for this request’s filter, row cap, and reveal choices. |
creditsEstimate: null | Export credit metering is not applied to this account or the current service configuration, including AYCE accounts. It is not an estimate error. |
Estimate, hold, and final charge
These are three different amounts:| Amount | Meaning |
|---|---|
| Estimate | A forecast based on audience counts and contact-detail availability. Counts and data can change; this is not a guaranteed ceiling. |
| Hold | Credits reserved when Export starts. With maxRows, it assumes every requested row has every selected contact detail. |
| Final charge | The rows actually written, populated selected details, and paid SmartSearch filter nodes. Unused held credits are released. |
maxRows: 100 and reveal: ["email"] require
a hold of up to 200 credits. If the file contains 100 contacts
but only 80 have an email, the final charge is 180 credits.
With both details selected, 100 contacts and one SmartSearch node
require a hold of up to 1,210 credits. If 80 have email and 20
have mobile, the final charge is 390 credits:
100 + 80 + (20 × 10) + 10.
402 INSUFFICIENT_CREDITS if it cannot
reserve that amount; it does not automatically export a smaller subset.Keep the request within a budget
Read your balance withGET /v2/account/balance. Current unit prices
are available from the free GET /v2/contact/credits/prices endpoint.
For an upper bound, allow 1, 2, 11, or 12 credits per contact row
according to the reveal table, plus 10 per SmartSearch node. With
200 credits and no SmartSearch nodes, an email-only export can cap at
100 rows. Using both details would cap at 16 rows. Always send a
positive maxRows; 0 does not mean a zero-row export.
Errors and next step
A503 ESTIMATE_UNAVAILABLE means the count used for the forecast
timed out. Do not interpret it as a zero-credit export. You can retry
after Retry-After, narrow the filter, or decide to proceed with an
explicit affordable maxRows and reveal upper bound.
A 422 means the request or filter needs correction. Estimate does
not validate every file-format, filename, or requested-column choice;
choose fields from the column catalog before starting the export.
On a 429, wait
for the rate-limit reset. No estimate response starts a paid job.
When the choices and budget are right, send the same body to
Export. Changing the filter, row cap,
or reveal choices requires a new estimate.Authorizations
Body
Audience filter, shared with Count and View. Omitted/null selects the entire dataset. Each semantic/lookalike node adds 10 credits on a paid export.
Show child attributes
Show child attributes
Fields written to the file. Omitted/null uses the default set; ["*"] requests all. Removing email/mobile columns does not remove reveal charges.
File format: csv, json (default), or parquet. Does not change unit credit prices.
gz (default), zip, or none. Does not change unit credit prices.
Positive row cap, up to 1,000,000. With an explicit cap, the hold assumes every selected contact detail is populated on every capped row. Omitted/null or 0 uses the maximum; 0 does not mean zero rows.
Optional base filename: 1–150 letters, digits, spaces, or . _ ( ) -. The API adds the selected file/compression extension.
Buy email (+1 per populated value), mobile (+10), both, or neither ([]), in addition to 1 per contact row. Omitted/null buys both. Columns do not change these charges. Unselected requested fields become availability booleans.
Response
Successful Response
The response is of type Response Estimate Export V1 Exports Estimate Post · object.
Was this page helpful?
