Create imports

Creates an import into one of the org's lists and answers it.

POST /v1/marketing/imports

Addresshttps://api.hanzo.ai/v1/marketing/imports
MethodPOST
Operationpost_marketing_imports
AuthAuthorization: Bearer $HANZO_API_KEY

Creates an import into one of the org's lists and answers it. For a file the import waits in state receiving for its bytes (PUT /v1/marketing/imports/{id}/data); for a source (from: commerce) it is queued at once. A key makes the call idempotent: a second create with it answers the first import. The rows are stamped with the import's id as their source ref, so a filter on ref selects the batch.

Org admin only.

Request

22 fields, body application/json (required).

FieldInTypeRequiredDescription
basisbodystring—Basis is the consent basis recorded for every row: explicit, legitimate_interest or unverified (the default).
dryRunbodyboolean—DryRun reads and judges every row and writes nothing.
formatbodystring—Format is csv or json; ignored for a source.
frombodystring—From is a source to read instead of a file, as the host offers them: commerce (the org's commerce form subscribers) or crm (the confirmations the retired newsletter filed in the org's CRM).
keybodystring—Key makes creating the import idempotent: a second create with the same key answers the first import.
listbodystring—List is the list to fill, by id or slug.
mapbodymarketing.Mapping—
map.consentAtbodystring—ConsentAt is a column holding when the person subscribed.
map.emailbodystring—Email is the column holding the address.
map.fieldsbodyobject—Fields maps a custom field key to the column holding it.
map.fields.*bodystring—
map.firstbodystring—First and Last are columns holding the name in two parts.
map.languagebodystring—Language is a column holding a language or locale.
map.lastbodystring—Last is the family name's column.
map.namebodystring—Name is a column holding the whole name.
map.statusbodystring—Status is a column holding a status from another provider (subscribed, unsubscribed, cleaned, bounced, complained and their usual spellings).
map.tagsbodystring—Tags is a column of tags separated by commas or semicolons.
namebodystring—Name is the file's name, for the record.
sizebodyinteger (int64)—Size is the file's size in bytes, when known; the upload is refused past it.
statusbodystring—Status is what a new row becomes: subscribed (the default), unsubscribed, bounced, complained or cleaned, as an export from another provider records.
tagsbodystring[]—Tags are put on every row the import writes.
verifybodyboolean—Verify checks each address deliverable before writing it.

Response

StatusBodyMeaning
200marketing.Createdok
201marketing.Createdcreated
defaultproblem-detailsrefused

200 body — 60 fields.

FieldInTypeAlwaysDescription
bybodystring—By is who created it.
createdAtbodyinteger (int64)—CreatedAt, UpdatedAt and FinishedAt are unix seconds.
errorbodystring—Error is why a failed import stopped.
existedbodyboolean—Existed is true when an import with the same key was already there.
finishedAtbodyinteger (int64)—FinishedAt is when it ended; 0 while it runs.
idbodystring—ID is the import's id ("imp_" and 96 random bits in hex): the batch every subscriber it adds records as its source ref.
listbodystring—List is the list it fills.
optionsbodymarketing.ImportOptions—
options.basisbodystring—Basis is the consent basis recorded for every row: explicit, legitimate_interest or unverified (the default).
options.dryRunbodyboolean—DryRun reads and judges every row and writes nothing.
options.formatbodystring—Format is csv or json; ignored for a source.
options.frombodystring—From is a source to read instead of a file, as the host offers them: commerce (the org's commerce form subscribers) or crm (the confirmations the retired newsletter filed in the org's CRM).
options.keybodystring—Key makes creating the import idempotent: a second create with the same key answers the first import.
options.mapbodymarketing.Mapping—
options.map.consentAtbodystring—ConsentAt is a column holding when the person subscribed.
options.map.emailbodystring—Email is the column holding the address.
options.map.fieldsbodyobject—Fields maps a custom field key to the column holding it.
options.map.fields.*bodystring—
options.map.firstbodystring—First and Last are columns holding the name in two parts.
options.map.languagebodystring—Language is a column holding a language or locale.
options.map.lastbodystring—Last is the family name's column.
options.map.namebodystring—Name is a column holding the whole name.
options.map.statusbodystring—Status is a column holding a status from another provider (subscribed, unsubscribed, cleaned, bounced, complained and their usual spellings).
options.map.tagsbodystring—Tags is a column of tags separated by commas or semicolons.
options.namebodystring—Name is the file's name, for the record.
options.sizebodyinteger (int64)—Size is the file's size in bytes, when known; the upload is refused past it.
options.statusbodystring—Status is what a new row becomes: subscribed (the default), unsubscribed, bounced, complained or cleaned, as an export from another provider records.
options.tagsbodystring[]—Tags are put on every row the import writes.
options.verifybodyboolean—Verify checks each address deliverable before writing it.
parsedbodyinteger (int64)—Parsed is how many bytes of the file the worker has read and judged.
receivedbodyinteger (int64)—Received is how many bytes of the file have arrived; the next piece starts here.
reportbodymarketing.Report—
report.basesbodyobject—Bases count the rows written by the consent basis recorded for them.
report.bases.*bodyinteger (int64)—
report.columnsbodystring[]—Columns are the file's columns, as its header named them.
report.importedbodyinteger (int64)—Imported is how many rows became new subscribers.
report.invalidbodyinteger (int64)—Invalid is how many could not be read as an address, for the reasons in Reasons.
report.mapbodymarketing.Mapping—
report.map.consentAtbodystring—ConsentAt is a column holding when the person subscribed.
report.map.emailbodystring—Email is the column holding the address.
report.map.fieldsbodyobject—Fields maps a custom field key to the column holding it.
report.map.fields.*bodystring—
report.map.firstbodystring—First and Last are columns holding the name in two parts.
report.map.languagebodystring—Language is a column holding a language or locale.
report.map.lastbodystring—Last is the family name's column.
report.map.namebodystring—Name is a column holding the whole name.
report.map.statusbodystring—Status is a column holding a status from another provider (subscribed, unsubscribed, cleaned, bounced, complained and their usual spellings).
report.map.tagsbodystring—Tags is a column of tags separated by commas or semicolons.
report.reasonsbodyobject—Reasons count the skipped and invalid rows by why.
report.reasons.*bodyinteger (int64)—
report.rowsbodyinteger (int64)—Rows is how many rows were read.
report.samplesbodymarketing.Sample[]—Samples are the first rejected rows: their row number and the reason.
report.samples[].reasonbodystring—Reason is why it was rejected.
report.samples[].rowbodyinteger (int64)—Row is the row's number in the file, the header not counted.
report.skippedbodyinteger (int64)—Skipped is how many were left as they were, for the reasons in Reasons.
report.statusesbodyobject—Statuses count the rows written by the status they were written with.
report.statuses.*bodyinteger (int64)—
report.updatedbodyinteger (int64)—Updated is how many were already on the list and gained a name, tags or fields, or a status that leaves the list.
statebodystring—State is receiving (waiting for its bytes), queued, processing, done, failed or cancelled.
updatedAtbodyinteger (int64)—UpdatedAt is the last progress.

Failure carries the platform error shape — see Errors.

Examples

hanzo marketing imports create
import { Configuration, MarketingApi } from 'hanzoai';

const api = new MarketingApi(new Configuration({ accessToken: process.env.HANZO_API_KEY }));
const { data } = await api.postMarketingImports({ basis: "<basis>", dryRun: false });
from hanzoai.cloud import ApiClient, Configuration
from hanzoai.cloud.api import MarketingApi

client = ApiClient(Configuration(access_token=os.environ["HANZO_API_KEY"]))
result = MarketingApi(client).post_marketing_imports(basis="<basis>", dry_run=False)
cfg := hanzoai.NewConfiguration()
cfg.AddDefaultHeader("Authorization", "Bearer "+os.Getenv("HANZO_API_KEY"))
client := hanzoai.NewAPIClient(cfg)

resp, _, err := client.MarketingAPI.PostMarketingImports(context.Background()).Execute()
if err != nil {
	return err
}
use hanzo_client::apis::{configuration::Configuration, marketing_api};

let mut cfg = Configuration::new();
cfg.bearer_access_token = std::env::var("HANZO_API_KEY").ok();

let result = marketing_api::post_marketing_imports(&cfg, Default::default()).await?;
import ai.hanzo.cloud.ApiClient;
import ai.hanzo.cloud.api.MarketingApi;

ApiClient client = new ApiClient();
client.setBearerToken(System.getenv("HANZO_API_KEY"));

var result = new MarketingApi(client).postMarketingImports();

The method above is the one at the current release of the document. [email protected] (npm) and [email protected] (PyPI) were generated from an earlier release, where this operation carried a different id, so it spells the method differently — regenerating the clients is what makes the two agree. SDKs →

curl -X POST https://api.hanzo.ai/v1/marketing/imports \
  -H "Authorization: Bearer $HANZO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
       "basis": "<basis>",
       "dryRun": false
     }'

MCP reaches marketing through the marketing tool, which names its 82 operations with its own verbs — this one among them, under a name only MCP declares. describe explains any of them:

curl -X POST https://api.hanzo.ai/v1/mcp \
  -H "Content-Type: application/json" \
  -d '{
       "jsonrpc": "2.0",
       "id": 1,
       "method": "tools/call",
       "params": {
         "name": "describe",
         "arguments": {
           "op": "list_marketing_audiences"
         }
       }
     }'

Marketing API · All Hanzo APIs · Interactive reference

Was this page useful?
Broken link or missing step? Drop it in #docs on Discord or open a PR.