The file is fetched over HTTPS through the same SSRF-guarded fetcher POST /contact-lists/import uses: private and link-local addresses are refused and re-checked on every redirect, and the 50 MB cap is enforced while streaming rather than trusted from Content-Length. Fetching and staging happen before this call returns; the rows are written afterwards, which is why the status is 202. Poll GET /email/lists/imports/{id}.
Role addresses such as info@ and admin@ are always removed at import; there is no option to keep them. Addresses currently held out of sending by send-time screening are imported but held back, and counted as screened in the import summary.
mapping is optional. Omit it and the platform uses the mapping it recognizes from the export’s own headers, which is what a caller exporting from a common ESP wants. When neither your mapping nor the recognizer finds an email column the request returns 400 VALIDATION_ERROR with details.headers listing the headers that were read, so the retry can name the right column instead of guessing.
Optional idempotency key: a unique string of 16-200 printable ASCII characters (a UUID is recommended). Retrying the write with the same key within 24 hours returns the stored response of the first call with an X-Idempotent-Replayed: true response header instead of executing it again. Reusing a key with a different request body returns 422 (IDEMPOTENCY_MISMATCH); a duplicate sent while the first call is still running returns 409 with a Retry-After header. Keys are scoped per endpoint and organization.
Name for the list this file becomes. Defaults to the file name. The uploaded file IS the list: an import creates one rather than adding to an existing list.
One import of a caller-hosted CSV into an email list.
Show child attributes
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Political Comms","description":"Documentation for the Political Comms P2P texting platform - help center, onboarding, compliance, and API reference.","colors":{"primary":"#1E3A8A","light":"#3B82F6","dark":"#1E3A8A"},"logo":{"light":"https://mintcdn.com/politicalcomms/EWPdkQOGp2k4Npo5/logo/main.png?fit=max\u0026auto=format\u0026n=EWPdkQOGp2k4Npo5\u0026q=85\u0026s=694b5108d71882d5774bc62c478bc370","dark":"https://mintcdn.com/politicalcomms/EWPdkQOGp2k4Npo5/logo/main.png?fit=max\u0026auto=format\u0026n=EWPdkQOGp2k4Npo5\u0026q=85\u0026s=694b5108d71882d5774bc62c478bc370","href":"/"},"favicon":"https://mintcdn.com/politicalcomms/EWPdkQOGp2k4Npo5/favicon.png?fit=max\u0026auto=format\u0026n=EWPdkQOGp2k4Npo5\u0026q=85\u0026s=63a87e09739757db232880f7adfda947","navbar":{"links":[{"href":"mailto:support@politicalcomms.com","label":"Support"}],"primary":{"type":"button","label":"Sign in","href":"https://app.politicalcomms.com"}},"footer":{"socials":{"website":"https://politicalcomms.com"},"links":[{"header":"Product","items":[{"label":"Dashboard","href":"https://app.politicalcomms.com"},{"label":"Pricing","href":"https://politicalcomms.com/pricing"},{"label":"Status","href":"https://status.politicalcomms.com"}]},{"header":"Resources","items":[{"label":"Help Center","href":"/help/getting-started"},{"label":"Onboarding","href":"/onboarding/overview"},{"label":"Compliance","href":"/compliance/overview"},{"label":"API Reference","href":"/api-reference/introduction"}]},{"header":"Legal","items":[{"label":"Terms of Use","href":"/legal/terms"},{"label":"Privacy Policy","href":"/legal/privacy"}]}]},"seo":{"metatags":{"og:site_name":"Political Comms Docs","og:type":"website","og:locale":"en_US","og:image":"https://politicalcomms.com/opengraph-image","og:image:width":"1200","og:image:height":"630","og:image:alt":"Political Comms. The direct-to-carrier political texting platform.","twitter:card":"summary_large_image","twitter:image":"https://politicalcomms.com/opengraph-image","twitter:image:alt":"Political Comms. The direct-to-carrier political texting platform.","robots":"index, follow, max-image-preview:large, max-snippet:-1","author":"Political Comms","publisher":"Political Comms","application-name":"Political Comms Docs","apple-mobile-web-app-title":"Political Comms Docs","theme-color":"#254692","msapplication-TileColor":"#254692","category":"Political Technology, Communications Infrastructure","keywords":"political texting, political SMS, P2P messaging, 10DLC registration, Campaign Verify, TCPA compliance, FCC political rules, MCP server, AI agent integration"},"indexing":"all"},"styling":{"latex":true},"navigation":{"global":{"anchors":[{"anchor":"Dashboard","icon":"arrow-up-right-from-square","href":"https://app.politicalcomms.com"},{"anchor":"Status","icon":"signal","href":"https://status.politicalcomms.com"},{"anchor":"Changelog","icon":"clock-rotate-left","href":"/changelog"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"politicalcomms","hasAudioNarration":false,"actualSubdomain":"politicalcomms","customDomains":["docs.politicalcomms.com"],"gitSource":{"type":"github","owner":"political-comms","repo":"political-comms-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6aced098cad5d0b6dc390f54","collectionId":"c49dd96d-443e-4cbc-9c1d-3e8cd1735ae5","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6aced098cad5d0b6dc390f54"},"entitlements":{"AI_CHAT":{"status":"DISABLED"}},"buildId":"6aced098cad5d0b6dc390f54","clientVersion":"0.0.3969","searchFilterCounts":[{"language":"default","tag":"API Reference","count":69},{"language":"default","tag":"Endpoints","count":56},{"language":"default","tag":"Documentation","count":38},{"language":"default","tag":"Email","count":22},{"language":"default","tag":"Text","count":19},{"language":"default","tag":"Assets","count":15},{"language":"default","tag":"Projects","count":13},{"language":"default","tag":"Help Center","count":11},{"language":"default","tag":"Get Started","count":8},{"language":"default","tag":"Compliance","count":8}]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-v7-file-tree","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"pause-universal-search-reconcile","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"per-site-search-delta","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-private-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-nav-generations","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-agent-model-picker","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"isAtlas":false,"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"api-reference/email-lists/import-contacts-from-a-url","slug":"/api-reference/email-lists/import-contacts-from-a-url","pageMetadata":{"title":"Import Contacts From A URL","description":"Import contacts into a list from a CSV you host.\n\nThe file is fetched over HTTPS through the same SSRF-guarded fetcher `POST /contact-lists/import` uses: private and link-local addresses are refused and re-checked on every redirect, and the 50 MB cap is enforced while streaming rather than trusted from `Content-Length`. Fetching and staging happen before this call returns; the rows are written afterwards, which is why the status is `202`. Poll `GET /email/lists/imports/{id}`.\n\nRole addresses such as info@ and admin@ are always removed at import; there is no option to keep them. Addresses currently held out of sending by send-time screening are imported but held back, and counted as `screened` in the import summary.\n\n`mapping` is optional. Omit it and the platform uses the mapping it recognizes from the export's own headers, which is what a caller exporting from a common ESP wants. When neither your mapping nor the recognizer finds an email column the request returns `400 VALIDATION_ERROR` with `details.headers` listing the headers that were read, so the retry can name the right column instead of guessing.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/lists/import","href":"/api-reference/email-lists/import-contacts-from-a-url","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsx(_components.p, {\n children: \"Import contacts into a list from a CSV you host.\"\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"The file is fetched over HTTPS through the same SSRF-guarded fetcher \", _jsx(_components.code, {\n children: \"POST /contact-lists/import\"\n }), \" uses: private and link-local addresses are refused and re-checked on every redirect, and the 50 MB cap is enforced while streaming rather than trusted from \", _jsx(_components.code, {\n children: \"Content-Length\"\n }), \". Fetching and staging happen before this call returns; the rows are written afterwards, which is why the status is \", _jsx(_components.code, {\n children: \"202\"\n }), \". Poll \", _jsx(_components.code, {\n children: \"GET /email/lists/imports/{id}\"\n }), \".\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Role addresses such as info@ and admin@ are always removed at import; there is no option to keep them. Addresses currently held out of sending by send-time screening are imported but held back, and counted as \", _jsx(_components.code, {\n children: \"screened\"\n }), \" in the import summary.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.code, {\n children: \"mapping\"\n }), \" is optional. Omit it and the platform uses the mapping it recognizes from the export’s own headers, which is what a caller exporting from a common ESP wants. When neither your mapping nor the recognizer finds an email column the request returns \", _jsx(_components.code, {\n children: \"400 VALIDATION_ERROR\"\n }), \" with \", _jsx(_components.code, {\n children: \"details.headers\"\n }), \" listing the headers that were read, so the retry can name the right column instead of guessing.\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Import Contacts From A URL","description":"Import contacts into a list from a CSV you host.\n\nThe file is fetched over HTTPS through the same SSRF-guarded fetcher `POST /contact-lists/import` uses: private and link-local addresses are refused and re-checked on every redirect, and the 50 MB cap is enforced while streaming rather than trusted from `Content-Length`. Fetching and staging happen before this call returns; the rows are written afterwards, which is why the status is `202`. Poll `GET /email/lists/imports/{id}`.\n\nRole addresses such as info@ and admin@ are always removed at import; there is no option to keep them. Addresses currently held out of sending by send-time screening are imported but held back, and counted as `screened` in the import summary.\n\n`mapping` is optional. Omit it and the platform uses the mapping it recognizes from the export's own headers, which is what a caller exporting from a common ESP wants. When neither your mapping nor the recognizer finds an email column the request returns `400 VALIDATION_ERROR` with `details.headers` listing the headers that were read, so the retry can name the right column instead of guessing.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/lists/import","href":"/api-reference/email-lists/import-contacts-from-a-url","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"tags":["Email Lists"],"summary":"Import Contacts From A URL","description":"Import contacts into a list from a CSV you host.\n\nThe file is fetched over HTTPS through the same SSRF-guarded fetcher `POST /contact-lists/import` uses: private and link-local addresses are refused and re-checked on every redirect, and the 50 MB cap is enforced while streaming rather than trusted from `Content-Length`. Fetching and staging happen before this call returns; the rows are written afterwards, which is why the status is `202`. Poll `GET /email/lists/imports/{id}`.\n\nRole addresses such as info@ and admin@ are always removed at import; there is no option to keep them. Addresses currently held out of sending by send-time screening are imported but held back, and counted as `screened` in the import summary.\n\n`mapping` is optional. Omit it and the platform uses the mapping it recognizes from the export's own headers, which is what a caller exporting from a common ESP wants. When neither your mapping nor the recognizer finds an email column the request returns `400 VALIDATION_ERROR` with `details.headers` listing the headers that were read, so the retry can name the right column instead of guessing.","operationId":"importEmailListContacts","parameters":["2ef77aad-c19a-4392-ba7e-83093a9af887"],"requestBody":"3d714db2-5330-48ca-a5d0-575afa25bd2d","responses":{"202":"c2f52967-a1e9-4883-a92f-a6ef10b32aa6","400":"2abbe546-662b-4a1a-ba5c-a7510a0aeea9","401":"f86e1c31-32b2-4cdf-b195-33896efdf967","403":"10ee9f98-9438-4f90-9817-72e7148d2545","404":"2afa514c-8a15-4914-9421-3ed45529e05c","429":"f0ed52b8-8300-4f47-a156-81cfb1db26cd","500":"6feb8591-0337-44ac-b275-31ca5ba90bfa"},"method":"post","type":"path","servers":["11f00f60-ab90-4662-af62-52a52ea44f9a"],"security":["5099107a-b214-4863-8d56-f15e3d691058"],"path":"/email/lists/import","baseUrlOptions":["https://api.politicalcomms.com/v1"],"title":"Import Contacts From A URL","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"2ef77aad-c19a-4392-ba7e-83093a9af887":{"name":"Idempotency-Key","in":"header","required":false,"schema":{"type":"string","minLength":16,"maxLength":200,"isRequired":false,"description":"Optional idempotency key: a unique string of 16-200 printable ASCII characters (a UUID is recommended). Retrying the write with the same key within 24 hours returns the stored response of the first call with an `X-Idempotent-Replayed: true` response header instead of executing it again. Reusing a key with a different request body returns `422` (`IDEMPOTENCY_MISMATCH`); a duplicate sent while the first call is still running returns `409` with a `Retry-After` header. Keys are scoped per endpoint and organization.","uniqueKey":"","typeLabel":"string"},"description":"Optional idempotency key: a unique string of 16-200 printable ASCII characters (a UUID is recommended). Retrying the write with the same key within 24 hours returns the stored response of the first call with an `X-Idempotent-Replayed: true` response header instead of executing it again. Reusing a key with a different request body returns `422` (`IDEMPOTENCY_MISMATCH`); a duplicate sent while the first call is still running returns `409` with a `Retry-After` header. Keys are scoped per endpoint and organization."}},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"source_url":{"type":"string","format":"uri","description":"HTTPS URL of the CSV. Maximum 50 MB.","isRequired":true,"uniqueKey":"source_url","typeLabel":"string\u003curi>"},"consent":{"type":"object","properties":{"source":{"type":"string","enum":["donation_form","petition","signup_form","event","purchased","rented","other"],"description":"How these people agreed to hear from you. Answer honestly: `purchased` and `rented` change how the list is treated, and an undeclared acquired list is the usual cause of a mid-send deliverability pause.","isRequired":true,"uniqueKey":"consent.source","typeLabel":"enum\u003cstring>"},"note":{"type":"string","maxLength":1000,"uniqueKey":"consent.note","typeLabel":"string"}},"required":["source"],"additionalProperties":false,"isRequired":true,"uniqueKey":"consent","typeLabel":"object"},"name":{"type":"string","maxLength":255,"description":"Name for the list this file becomes. Defaults to the file name. The uploaded file IS the list: an import creates one rather than adding to an existing list.","uniqueKey":"name","typeLabel":"string"},"email_domain_id":{"type":"string","format":"uuid","description":"Scopes the list to one sending domain. Omit for an organization-wide list any campaign can use.","uniqueKey":"email_domain_id","typeLabel":"string\u003cuuid>"},"acquired":{"type":"boolean","description":"The addresses were purchased or rented. Acquired lists are not blocked from sending, but they ramp on half the normal warm-up steps.","uniqueKey":"acquired","typeLabel":"boolean"},"mapping":{"type":"object","additionalProperties":{"type":"string","maxLength":64,"uniqueKey":"mapping.additionalProperties","typeLabel":"string"},"description":"CSV header to contact field, for example `{\"Email Address\": \"email\", \"First\": \"first_name\"}`. Exactly one header must map to `email`.","uniqueKey":"mapping","typeLabel":"object"}},"required":["source_url","consent"],"additionalProperties":false,"uniqueKey":"","typeLabel":"object"},"example":{"source_url":"https://files.example.com/exports/august-donors.csv","name":"August donors","consent":{"source":"donation_form","note":"Donate page opt-in checkbox"}},"examples":{"Example":{"title":"Example","value":{"source_url":"https://files.example.com/exports/august-donors.csv","name":"August donors","consent":{"source":"donation_form","note":"Donate page opt-in checkbox"}}}},"exampleType":"examples"}},"exampleType":"examples"},"responses":{"c2f52967-a1e9-4883-a92f-a6ef10b32aa6":{"description":"Import accepted. Poll the import for progress.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","isRequired":true,"uniqueKey":"success","typeLabel":"boolean"},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid","isRequired":true,"uniqueKey":"data.id","typeLabel":"string\u003cuuid>"},"status":{"type":"string","description":"Import lifecycle state. Terminal states are `completed` and `failed`.","isRequired":true,"uniqueKey":"data.status","typeLabel":"string"},"email_list_id":{"oneOf":[{"type":"string","format":"uuid","uniqueKey":"data.email_list_id.oneOf.0","typeLabel":"string\u003cuuid>"},{"type":"null","format":"uuid","uniqueKey":"data.email_list_id.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.email_list_id","typeLabel":"string\u003cuuid> | null"},"file_name":{"oneOf":[{"type":"string","description":"Derived from the last path segment of `source_url`.","uniqueKey":"data.file_name.oneOf.0","typeLabel":"string"},{"type":"null","description":"Derived from the last path segment of `source_url`.","uniqueKey":"data.file_name.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.file_name","typeLabel":"string | null"},"file_size":{"type":"integer","description":"Bytes fetched.","uniqueKey":"data.file_size","typeLabel":"integer"},"headers":{"type":"array","items":{"type":"string","uniqueKey":"data.headers.items.[INDEX]","typeLabel":"string"},"description":"The CSV's header row as read. Echoed back so a caller that omitted `mapping` can see what the recognizer worked from.","uniqueKey":"data.headers","typeLabel":"string[]"},"mapping":{"type":"object","additionalProperties":{"type":"string","uniqueKey":"data.mapping.additionalProperties","typeLabel":"string"},"description":"CSV header to contact field. The mapping actually used, whether you sent it or the recognizer produced it.","uniqueKey":"data.mapping","typeLabel":"object"},"recognized_provider":{"oneOf":[{"type":"string","description":"The ESP whose export format was recognized, when one was.","uniqueKey":"data.recognized_provider.oneOf.0","typeLabel":"string"},{"type":"null","description":"The ESP whose export format was recognized, when one was.","uniqueKey":"data.recognized_provider.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.recognized_provider","typeLabel":"string | null"},"summary":{"oneOf":[{"type":"object","properties":{"screened":{"type":"integer","description":"Addresses currently held out of sending by send-time screening. They are imported but held back, and are checked again after the 90-day hold.","uniqueKey":"data.summary.oneOf.0.screened","typeLabel":"integer"}},"additionalProperties":true,"description":"Row counts once the import finishes, including `screened`.","uniqueKey":"data.summary.oneOf.0","typeLabel":"object"},{"type":"null","properties":{"screened":{"type":"integer","description":"Addresses currently held out of sending by send-time screening. They are imported but held back, and are checked again after the 90-day hold."}},"additionalProperties":true,"description":"Row counts once the import finishes, including `screened`.","uniqueKey":"data.summary.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.summary","typeLabel":"object | null"},"error_message":{"oneOf":[{"type":"string","uniqueKey":"data.error_message.oneOf.0","typeLabel":"string"},{"type":"null","uniqueKey":"data.error_message.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.error_message","typeLabel":"string | null"},"created_at":{"type":"string","format":"date-time","uniqueKey":"data.created_at","typeLabel":"string\u003cdate-time>"},"started_at":{"oneOf":[{"type":"string","format":"date-time","uniqueKey":"data.started_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","uniqueKey":"data.started_at.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.started_at","typeLabel":"string\u003cdate-time> | null"},"completed_at":{"oneOf":[{"type":"string","format":"date-time","uniqueKey":"data.completed_at.oneOf.0","typeLabel":"string\u003cdate-time>"},{"type":"null","format":"date-time","uniqueKey":"data.completed_at.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.completed_at","typeLabel":"string\u003cdate-time> | null"}},"required":["id","status"],"description":"One import of a caller-hosted CSV into an email list.","additionalProperties":true,"isRequired":true,"uniqueKey":"data","typeLabel":"object"}},"required":["success","data"],"additionalProperties":true,"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"success":true,"data":{"id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","status":"\u003cstring>","email_list_id":"3c90c3cc-0d44-4b50-8888-8dd25736052a","file_name":"\u003cstring>","file_size":123,"headers":["\u003cstring>"],"mapping":{},"recognized_provider":"\u003cstring>","summary":{"screened":123},"error_message":"\u003cstring>","created_at":"2023-11-07T05:31:56Z","started_at":"2023-11-07T05:31:56Z","completed_at":"2023-11-07T05:31:56Z"}}}},"exampleType":"generated"}},"exampleType":"generated"},"2abbe546-662b-4a1a-ba5c-a7510a0aeea9":{"description":"Invalid request (validation failure, malformed parameters, or a request the resource state does not allow).","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable error message.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"code":{"type":"string","description":"Machine-readable error code, e.g. VALIDATION_ERROR, ORG_ACCESS_DENIED, PROJECT_NOT_FOUND.","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"correlationId":{"type":"string","description":"Request correlation ID; include it in support requests.","uniqueKey":"correlationId","typeLabel":"string"},"details":{"oneOf":[{"type":"array","description":"Present on some errors. For VALIDATION_ERROR, an array of { field, message, code } with one entry per rejected field (field is the dotted path); an object for other codes (e.g. insufficient-balance shortfall).","uniqueKey":"details.oneOf.0","typeLabel":"array"},{"type":"object","description":"Present on some errors. For VALIDATION_ERROR, an array of { field, message, code } with one entry per rejected field (field is the dotted path); an object for other codes (e.g. insufficient-balance shortfall).","uniqueKey":"details.oneOf.1","typeLabel":"object"}],"uniqueKey":"details","typeLabel":"array | object"}},"required":["error","code"],"additionalProperties":true,"description":"Standard error body produced by the API error handler for 4xx/5xx responses.","uniqueKey":"","typeLabel":"object"},"example":{"error":"Validation failed","code":"VALIDATION_ERROR","correlationId":"030bf857-922f-4b82-8fca-c5b0769c1590","details":[{"field":"organization_id","message":"Invalid UUID","code":"invalid_format"}]},"examples":{"Example":{"title":"Example","value":{"error":"Validation failed","code":"VALIDATION_ERROR","correlationId":"030bf857-922f-4b82-8fca-c5b0769c1590","details":[{"field":"organization_id","message":"Invalid UUID","code":"invalid_format"}]}}},"exampleType":"examples"}},"exampleType":"examples"},"f86e1c31-32b2-4cdf-b195-33896efdf967":{"description":"Missing, malformed, revoked, or expired API key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Short error summary.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"message":{"type":"string","description":"Human-readable detail.","isRequired":true,"uniqueKey":"message","typeLabel":"string"}},"required":["error","message"],"additionalProperties":true,"description":"Error body returned by the API-key authentication layer (401 and permission 403s).","uniqueKey":"","typeLabel":"object"},"example":{"error":"API key required","message":"Please provide an API key in the X-API-Key header"},"examples":{"Example":{"title":"Example","value":{"error":"API key required","message":"Please provide an API key in the X-API-Key header"}}},"exampleType":"examples"}},"exampleType":"examples"},"10ee9f98-9438-4f90-9817-72e7148d2545":{"description":"The API key lacks the required permission scope, the requested resource belongs to an organization outside the key's hierarchy, or the organization is not entitled to this feature.","content":{"application/json":{"schema":{"oneOf":[{"type":"object","description":"Error body returned by the API-key authentication layer (401 and permission 403s).","required":["error","message"],"properties":{"error":{"type":"string","description":"Short error summary.","isRequired":true,"uniqueKey":"oneOf.0.error","typeLabel":"string"},"message":{"type":"string","description":"Human-readable detail.","isRequired":true,"uniqueKey":"oneOf.0.message","typeLabel":"string"}},"additionalProperties":true,"uniqueKey":"oneOf.0","typeLabel":"object"},{"type":"object","description":"Standard error body produced by the API error handler for 4xx/5xx responses.","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable error message.","isRequired":true,"uniqueKey":"oneOf.1.error","typeLabel":"string"},"code":{"type":"string","description":"Machine-readable error code, e.g. VALIDATION_ERROR, ORG_ACCESS_DENIED, PROJECT_NOT_FOUND.","isRequired":true,"uniqueKey":"oneOf.1.code","typeLabel":"string"},"correlationId":{"type":"string","description":"Request correlation ID; include it in support requests.","uniqueKey":"oneOf.1.correlationId","typeLabel":"string"},"details":{"oneOf":[{"type":"array","description":"Present on some errors. For VALIDATION_ERROR, an array of { field, message, code } with one entry per rejected field (field is the dotted path); an object for other codes (e.g. insufficient-balance shortfall).","uniqueKey":"oneOf.1.details.oneOf.0","typeLabel":"array"},{"type":"object","description":"Present on some errors. For VALIDATION_ERROR, an array of { field, message, code } with one entry per rejected field (field is the dotted path); an object for other codes (e.g. insufficient-balance shortfall).","uniqueKey":"oneOf.1.details.oneOf.1","typeLabel":"object"}],"uniqueKey":"oneOf.1.details","typeLabel":"array | object"}},"additionalProperties":true,"uniqueKey":"oneOf.1","typeLabel":"object"}],"uniqueKey":"","typeLabel":"object"},"examples":{"missingScope":{"title":"missingScope","value":{"error":"Insufficient permissions","message":"This API key does not have the required permissions: public:read"}},"orgAccessDenied":{"title":"orgAccessDenied","value":{"error":"Access denied: You do not have permission to access this organization's data","code":"ORG_ACCESS_DENIED","correlationId":"de038205-7c9c-4d4a-99bc-d7275a52f07e"}},"entitlementRequired":{"title":"entitlementRequired","value":{"error":"This feature requires enablement by Political Comms","code":"ENTITLEMENT_REQUIRED","details":{"entitlement":"email"}}}},"exampleType":"examples"}},"exampleType":"examples"},"2afa514c-8a15-4914-9421-3ed45529e05c":{"description":"Resource not found or not visible to this API key.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable error message.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"code":{"type":"string","description":"Machine-readable error code, e.g. VALIDATION_ERROR, ORG_ACCESS_DENIED, PROJECT_NOT_FOUND.","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"correlationId":{"type":"string","description":"Request correlation ID; include it in support requests.","uniqueKey":"correlationId","typeLabel":"string"},"details":{"oneOf":[{"type":"array","description":"Present on some errors. For VALIDATION_ERROR, an array of { field, message, code } with one entry per rejected field (field is the dotted path); an object for other codes (e.g. insufficient-balance shortfall).","uniqueKey":"details.oneOf.0","typeLabel":"array"},{"type":"object","description":"Present on some errors. For VALIDATION_ERROR, an array of { field, message, code } with one entry per rejected field (field is the dotted path); an object for other codes (e.g. insufficient-balance shortfall).","uniqueKey":"details.oneOf.1","typeLabel":"object"}],"uniqueKey":"details","typeLabel":"array | object"}},"required":["error","code"],"additionalProperties":true,"description":"Standard error body produced by the API error handler for 4xx/5xx responses.","uniqueKey":"","typeLabel":"object"},"example":{"error":"Project not found","code":"PROJECT_NOT_FOUND","correlationId":"de038205-7c9c-4d4a-99bc-d7275a52f07e"},"examples":{"Example":{"title":"Example","value":{"error":"Project not found","code":"PROJECT_NOT_FOUND","correlationId":"de038205-7c9c-4d4a-99bc-d7275a52f07e"}}},"exampleType":"examples"}},"exampleType":"examples"},"f0ed52b8-8300-4f47-a156-81cfb1db26cd":{"description":"Rate limit exceeded. Check the Retry-After header.","headers":{"Retry-After":{"description":"Seconds until the window resets.","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","enum":[false],"isRequired":true,"uniqueKey":"success","typeLabel":"enum\u003cboolean>"},"error":{"type":"string","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"code":{"type":"string","enum":["RATE_LIMIT_EXCEEDED"],"isRequired":true,"uniqueKey":"code","typeLabel":"enum\u003cstring>"},"statusCode":{"type":"integer","enum":[429],"isRequired":true,"uniqueKey":"statusCode","typeLabel":"enum\u003cinteger>"},"retryAfter":{"type":"integer","description":"Seconds until the rate-limit window resets. Also sent as the Retry-After header.","isRequired":true,"uniqueKey":"retryAfter","typeLabel":"integer"},"message":{"type":"string","uniqueKey":"message","typeLabel":"string"}},"required":["success","error","code","statusCode","retryAfter"],"additionalProperties":true,"uniqueKey":"","typeLabel":"object"},"example":{"success":false,"error":"Rate limit exceeded","message":"Maximum 600 requests per 60 seconds","code":"RATE_LIMIT_EXCEEDED","statusCode":429,"retryAfter":3},"examples":{"Example":{"title":"Example","value":{"success":false,"error":"Rate limit exceeded","message":"Maximum 600 requests per 60 seconds","code":"RATE_LIMIT_EXCEEDED","statusCode":429,"retryAfter":3}}},"exampleType":"examples"}},"exampleType":"examples"},"6feb8591-0337-44ac-b275-31ca5ba90bfa":{"description":"Unexpected server error.","content":{"application/json":{"schema":{"type":"object","properties":{"error":{"type":"string","description":"Human-readable error message.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"code":{"type":"string","description":"Machine-readable error code, e.g. VALIDATION_ERROR, ORG_ACCESS_DENIED, PROJECT_NOT_FOUND.","isRequired":true,"uniqueKey":"code","typeLabel":"string"},"correlationId":{"type":"string","description":"Request correlation ID; include it in support requests.","uniqueKey":"correlationId","typeLabel":"string"},"details":{"oneOf":[{"type":"array","description":"Present on some errors. For VALIDATION_ERROR, an array of { field, message, code } with one entry per rejected field (field is the dotted path); an object for other codes (e.g. insufficient-balance shortfall).","uniqueKey":"details.oneOf.0","typeLabel":"array"},{"type":"object","description":"Present on some errors. For VALIDATION_ERROR, an array of { field, message, code } with one entry per rejected field (field is the dotted path); an object for other codes (e.g. insufficient-balance shortfall).","uniqueKey":"details.oneOf.1","typeLabel":"object"}],"uniqueKey":"details","typeLabel":"array | object"}},"required":["error","code"],"additionalProperties":true,"description":"Standard error body produced by the API error handler for 4xx/5xx responses.","uniqueKey":"","typeLabel":"object"},"example":{"error":"An unexpected error occurred. Please try again later.","code":"INTERNAL_ERROR","correlationId":"de038205-7c9c-4d4a-99bc-d7275a52f07e"},"examples":{"Example":{"title":"Example","value":{"error":"An unexpected error occurred. Please try again later.","code":"INTERNAL_ERROR","correlationId":"de038205-7c9c-4d4a-99bc-d7275a52f07e"}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{"5099107a-b214-4863-8d56-f15e3d691058":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Authenticate every request by passing your API key in the X-API-Key header. Keys are scoped to your organization hierarchy.","scopes":[],"schemeName":"ApiKeyAuth"}}},"servers":{"11f00f60-ab90-4662-af62-52a52ea44f9a":{"url":"https://api.politicalcomms.com/v1","description":"Production"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Authenticate every request by passing your API key in the X-API-Key header. Keys are scoped to your organization hierarchy.","scopes":[],"schemeName":"ApiKeyAuth"},"schema":{"title":"X-API-Key","type":"string","description":"Authenticate every request by passing your API key in the X-API-Key header. Keys are scoped to your organization hierarchy.","isRequired":true,"typeLabel":"string","deprecated":false},"schemeName":"ApiKeyAuth","name":"X-API-Key"}],"title":"ApiKeyAuth"}]},"originalFileLocation":"api-reference/openapi.json"},"subdomain":"politicalcomms","siteName":"Political Comms","title":"Import Contacts From A URL - Political Comms","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-14T00:45:18.418Z","originalFileLocation":"api-reference/email-lists/import-contacts-from-a-url.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Import contacts into a list from a CSV you host. The file is fetched over HTTPS through the same SSRF-guarded fetcher POST /contact-lists/import uses: private and link-local addresses are refused and re-checked on every redirect, and the 50 MB cap is enforced while streaming rather than trusted from Content-Length. Fetching and staging happen before this call returns; the rows are written afterwards, which is why the status is 202. Poll GET /email/lists/imports/{id}. Role addresses such as info@ and admin@ are always removed at import; there is no option to keep them. Addresses currently held out of sending by send-time screening are imported but held back, and counted as screened in the import summary. mapping is optional. Omit it and the platform uses the mapping it recognizes from the export\u0026#x27;s own headers, which is what a caller exporting from a common ESP wants. When neither your mapping nor the recognizer finds an email column the request returns 400 VALIDATION_ERROR with details.headers listing the headers that were read, so the retry can name the right column instead of guessing.\">\u003cmeta data-mint-head name=\"keywords\" content=\"political texting, political SMS, P2P messaging, 10DLC registration, Campaign Verify, TCPA compliance, FCC political rules, MCP server, AI agent integration\">\u003cmeta data-mint-head name=\"application-name\" content=\"Political Comms\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003cmeta data-mint-head name=\"robots\" content=\"index, follow, max-image-preview:large, max-snippet:-1\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Import Contacts From A URL - Political Comms\">\u003cmeta data-mint-head property=\"og:description\" content=\"Import contacts into a list from a CSV you host. The file is fetched over HTTPS through the same SSRF-guarded fetcher POST /contact-lists/import uses: private and link-local addresses are refused and re-checked on every redirect, and the 50 MB cap is enforced while streaming rather than trusted from Content-Length. Fetching and staging happen before this call returns; the rows are written afterwards, which is why the status is 202. Poll GET /email/lists/imports/{id}. Role addresses such as info@ and admin@ are always removed at import; there is no option to keep them. Addresses currently held out of sending by send-time screening are imported but held back, and counted as screened in the import summary. mapping is optional. Omit it and the platform uses the mapping it recognizes from the export\u0026#x27;s own headers, which is what a caller exporting from a common ESP wants. When neither your mapping nor the recognizer finds an email column the request returns 400 VALIDATION_ERROR with details.headers listing the headers that were read, so the retry can name the right column instead of guessing.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Political Comms Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.politicalcomms.com/api-reference/email-lists/import-contacts-from-a-url\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://politicalcomms.com/opengraph-image\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Import Contacts From A URL - Political Comms\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Import contacts into a list from a CSV you host. The file is fetched over HTTPS through the same SSRF-guarded fetcher POST /contact-lists/import uses: private and link-local addresses are refused and re-checked on every redirect, and the 50 MB cap is enforced while streaming rather than trusted from Content-Length. Fetching and staging happen before this call returns; the rows are written afterwards, which is why the status is 202. Poll GET /email/lists/imports/{id}. Role addresses such as info@ and admin@ are always removed at import; there is no option to keep them. Addresses currently held out of sending by send-time screening are imported but held back, and counted as screened in the import summary. mapping is optional. Omit it and the platform uses the mapping it recognizes from the export\u0026#x27;s own headers, which is what a caller exporting from a common ESP wants. When neither your mapping nor the recognizer finds an email column the request returns 400 VALIDATION_ERROR with details.headers listing the headers that were read, so the retry can name the right column instead of guessing.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://politicalcomms.com/opengraph-image\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/politicalcomms/3u6PEpheVhjd9O_C/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Political Comms Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#254692\">\u003cmeta data-mint-head name=\"og:locale\" content=\"en_US\">\u003cmeta data-mint-head name=\"og:image:alt\" content=\"Political Comms. The direct-to-carrier political texting platform.\">\u003cmeta data-mint-head name=\"twitter:image:alt\" content=\"Political Comms. The direct-to-carrier political texting platform.\">\u003cmeta data-mint-head name=\"author\" content=\"Political Comms\">\u003cmeta data-mint-head name=\"publisher\" content=\"Political Comms\">\u003cmeta data-mint-head name=\"application-name\" content=\"Political Comms Docs\">\u003cmeta data-mint-head name=\"theme-color\" content=\"#254692\">\u003cmeta data-mint-head name=\"category\" content=\"Political Technology, Communications Infrastructure\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.politicalcomms.com/api-reference/email-lists/import-contacts-from-a-url\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/email-lists/import-contacts-from-a-url.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.politicalcomms.com/#organization\",\"name\":\"Political Comms\",\"url\":\"https://docs.politicalcomms.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/politicalcomms/EWPdkQOGp2k4Npo5/logo/main.png?fit=max\u0026auto=format\u0026n=EWPdkQOGp2k4Npo5\u0026q=85\u0026s=694b5108d71882d5774bc62c478bc370\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.politicalcomms.com#website\",\"name\":\"Political Comms\",\"url\":\"https://docs.politicalcomms.com\",\"publisher\":{\"@id\":\"https://docs.politicalcomms.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.politicalcomms.com/api-reference/email-lists/import-contacts-from-a-url#webpage\",\"url\":\"https://docs.politicalcomms.com/api-reference/email-lists/import-contacts-from-a-url\",\"name\":\"Import Contacts From A URL\",\"description\":\"Import contacts into a list from a CSV you host. The file is fetched over HTTPS through the same SSRF-guarded fetcher POST /contact-lists/import uses: private and link-local addresses are refused and re-checked on every redirect, and the 50 MB cap is enforced while streaming rather than trusted from Content-Length. Fetching and staging happen before this call returns; the rows are written afterwards, which is why the status is 202. Poll GET /email/lists/imports/{id}. Role addresses such as info@ and admin@ are always removed at import; there is no option to keep them. Addresses currently held out of sending by send-time screening are imported but held back, and counted as screened in the import summary. mapping is optional. Omit it and the platform uses the mapping it recognizes from the export's own headers, which is what a caller exporting from a common ESP wants. When neither your mapping nor the recognizer finds an email column the request returns 400 VALIDATION_ERROR with details.headers listing the headers that were read, so the retry can name the right column instead of guessing.\",\"dateModified\":\"2026-10-14T00:45:18.418Z\",\"isPartOf\":{\"@id\":\"https://docs.politicalcomms.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.politicalcomms.com/api-reference/email-lists/import-contacts-from-a-url#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.politicalcomms.com/api-reference/email-lists/import-contacts-from-a-url#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Endpoints\",\"item\":\"https://docs.politicalcomms.com/api-reference/projects/list-projects\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Assets\",\"item\":\"https://docs.politicalcomms.com/api-reference/contact-lists/list-contact-lists\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Email Lists\",\"item\":\"https://docs.politicalcomms.com/api-reference/email-lists/list-email-lists\"},{\"@type\":\"ListItem\",\"position\":4,\"name\":\"Import Contacts From A URL\",\"item\":\"https://docs.politicalcomms.com/api-reference/email-lists/import-contacts-from-a-url\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.politicalcomms.com/api-reference/email-lists/import-contacts-from-a-url#apireference\",\"headline\":\"Import Contacts From A URL\",\"name\":\"Import Contacts From A URL\",\"description\":\"Import contacts into a list from a CSV you host. The file is fetched over HTTPS through the same SSRF-guarded fetcher POST /contact-lists/import uses: private and link-local addresses are refused and re-checked on every redirect, and the 50 MB cap is enforced while streaming rather than trusted from Content-Length. Fetching and staging happen before this call returns; the rows are written afterwards, which is why the status is 202. Poll GET /email/lists/imports/{id}. Role addresses such as info@ and admin@ are always removed at import; there is no option to keep them. Addresses currently held out of sending by send-time screening are imported but held back, and counted as screened in the import summary. mapping is optional. Omit it and the platform uses the mapping it recognizes from the export's own headers, which is what a caller exporting from a common ESP wants. When neither your mapping nor the recognizer finds an email column the request returns 400 VALIDATION_ERROR with details.headers listing the headers that were read, so the retry can name the right column instead of guessing.\",\"url\":\"https://docs.politicalcomms.com/api-reference/email-lists/import-contacts-from-a-url\",\"mainEntityOfPage\":{\"@id\":\"https://docs.politicalcomms.com/api-reference/email-lists/import-contacts-from-a-url#webpage\"},\"image\":\"https://politicalcomms.com/opengraph-image\",\"dateModified\":\"2026-10-14T00:45:18.418Z\",\"publisher\":{\"@id\":\"https://docs.politicalcomms.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.politicalcomms.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Political Comms\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Political Comms","nav":{"global":{"anchors":[{"anchor":"Dashboard","icon":"arrow-up-right-from-square","href":"https://app.politicalcomms.com"},{"anchor":"Status","icon":"signal","href":"https://status.politicalcomms.com"},{"anchor":"Changelog","icon":"clock-rotate-left","href":"/changelog"}]},"tabs":[{"tab":"Documentation","pages":[{"title":"Documentation","href":"/introduction"}]},{"tab":"API Reference","groups":[{"group":"Introduction","pages":[{"title":"Introduction","icon":"code","href":"/api-reference/introduction"},{"title":"Authentication","icon":"key","href":"/api-reference/authentication"},{"title":"Rate Limits","icon":"gauge-high","href":"/api-reference/rate-limits"},{"title":"Error Handling","icon":"circle-exclamation","href":"/api-reference/errors"},{"title":"Versioning \u0026 Deprecation","href":"/api-reference/versioning"},{"title":"Best Practices","icon":"stars","href":"/api-reference/best-practices"},{"title":"Two-Way Conversations","icon":"messages","href":"/api-reference/two-way-conversations"}]},{"group":"Webhooks","pages":[{"title":"Overview","icon":"webhook","href":"/api-reference/webhooks/overview"},{"title":"Setup \u0026 Configuration","icon":"plug","href":"/api-reference/webhooks/setup"},{"title":"Signature Validation","icon":"shield-check","href":"/api-reference/webhooks/signature-validation"},{"title":"Event Types","icon":"code","href":"/api-reference/webhooks/events"},{"title":"Delivery Error Codes","icon":"triangle-exclamation","href":"/api-reference/webhooks/error-codes"},{"title":"Retry Policy","icon":"rotate-right","href":"/api-reference/webhooks/retry-policy"}]},{"group":"Endpoints","pages":[{"group":"Text","pages":[{"group":"Projects","pages":[{"title":"List Projects","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /projects","href":"/api-reference/projects/list-projects"},{"title":"Create Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /projects","href":"/api-reference/projects/create-project"},{"title":"Get Project Stats (all)","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /projects/stats","href":"/api-reference/projects/get-project-stats-all"},{"title":"Get Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /projects/{id}","href":"/api-reference/projects/get-project"},{"title":"Update Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json patch /projects/{id}","href":"/api-reference/projects/update-project"},{"title":"Get Project Stats (single)","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /projects/{id}/stats","href":"/api-reference/projects/get-project-stats-single"},{"title":"Get Project Throughput","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /projects/{id}/throughput","href":"/api-reference/projects/get-project-throughput"},{"title":"Get Survey Results","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /projects/{id}/survey-results","href":"/api-reference/projects/get-survey-results"},{"title":"Test Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /projects/{id}/test","href":"/api-reference/projects/test-project"},{"title":"Schedule Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /projects/{id}/schedule","href":"/api-reference/projects/schedule-project"},{"title":"Unschedule Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /projects/{id}/unschedule","href":"/api-reference/projects/unschedule-project"},{"title":"Pause Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /projects/{id}/pause","href":"/api-reference/projects/pause-project"},{"title":"Copy Project","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /projects/{id}/copy","href":"/api-reference/projects/copy-project"}]},{"group":"Phone Numbers","pages":[{"title":"List Phone Numbers","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /phone-numbers","href":"/api-reference/phone-numbers/list-phone-numbers"}]},{"group":"Toll-Free Verifications","pages":[{"title":"List Toll-Free Verifications","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /toll-free-verifications","href":"/api-reference/toll-free-verifications/list-toll-free-verifications"},{"title":"Get Toll-Free Verification","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /toll-free-verifications/{id}","href":"/api-reference/toll-free-verifications/get-toll-free-verification"}]},{"group":"Brands","pages":[{"title":"List Brands","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /brands","href":"/api-reference/brands/list-brands"}]},{"group":"10DLC Campaigns","pages":[{"title":"List Campaigns","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /campaigns","href":"/api-reference/10dlc-campaigns/list-campaigns"},{"title":"Get Campaign Throughput","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /campaigns/{id}/throughput","href":"/api-reference/10dlc-campaigns/get-campaign-throughput"}]}]},{"group":"Email","pages":[{"group":"Email Campaigns","pages":[{"title":"List Campaigns","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/campaigns","href":"/api-reference/email-campaigns/list-campaigns"},{"title":"Create Campaign","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/campaigns","href":"/api-reference/email-campaigns/create-campaign"},{"title":"Get Campaign","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/campaigns/{id}","href":"/api-reference/email-campaigns/get-campaign"},{"title":"Schedule Campaign","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/campaigns/{id}/schedule","href":"/api-reference/email-campaigns/schedule-campaign"},{"title":"Unschedule Campaign","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/campaigns/{id}/unschedule","href":"/api-reference/email-campaigns/unschedule-campaign"},{"title":"Get Campaign Stats","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/campaigns/{id}/stats","href":"/api-reference/email-campaigns/get-campaign-stats"}]},{"group":"Email Templates","pages":[{"title":"List Email Templates","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/templates","href":"/api-reference/email-templates/list-email-templates"},{"title":"Create Email Template","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/templates","href":"/api-reference/email-templates/create-email-template"},{"title":"Get Email Template","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/templates/{id}","href":"/api-reference/email-templates/get-email-template"}]},{"group":"Email Senders","pages":[{"title":"List Sender Identities","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/senders","href":"/api-reference/email-senders/list-sender-identities"},{"title":"Get Sender Identity","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/senders/{id}","href":"/api-reference/email-senders/get-sender-identity"}]},{"group":"Email Suppressions","pages":[{"title":"List Suppressions","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/suppressions","href":"/api-reference/email-suppressions/list-suppressions"},{"title":"Add Suppressions","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/suppressions","href":"/api-reference/email-suppressions/add-suppressions"},{"title":"Remove Suppressions","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json delete /email/suppressions","href":"/api-reference/email-suppressions/remove-suppressions"}]}]},{"group":"Assets","pages":[{"group":"Contact Lists","pages":[{"title":"List Contact Lists","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /contact-lists","href":"/api-reference/contact-lists/list-contact-lists"},{"title":"Get Contact List","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /contact-lists/{id}","href":"/api-reference/contact-lists/get-contact-list"},{"title":"Delete Contact List","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json delete /contact-lists/{id}","href":"/api-reference/contact-lists/delete-contact-list"},{"title":"Import Contact List","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /contact-lists/import","href":"/api-reference/contact-lists/import-contact-list"},{"title":"Analyze Contact List","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /contact-lists/{id}/analyze","href":"/api-reference/contact-lists/analyze-contact-list"}]},{"group":"Email Lists","pages":[{"title":"List Email Lists","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/lists","href":"/api-reference/email-lists/list-email-lists"},{"title":"Create Email List","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/lists","href":"/api-reference/email-lists/create-email-list"},{"title":"Get Email List","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/lists/{id}","href":"/api-reference/email-lists/get-email-list"},{"title":"List Contacts","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/lists/{id}/contacts","href":"/api-reference/email-lists/list-contacts"},{"title":"Add Contacts","description":"Upsert up to 1,000 contacts in one call. Invalid rows do not fail the request: every row comes back with its own outcome so you can fix just the rejected ones. Yahoo-run mailboxes (Yahoo, AOL, AT\u0026T, Verizon, Cox, Frontier) are never added to a list and come back `rejected` with reason `yahoo_family`, the same rule every upload applies.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/lists/{id}/contacts","href":"/api-reference/email-lists/add-contacts"},{"title":"Import Contacts From A URL","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /email/lists/import","href":"/api-reference/email-lists/import-contacts-from-a-url"}]},{"group":"Media Files","pages":[{"title":"List Media Files","description":"List all media files. Filter by organization or brand.","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /media","href":"/api-reference/media-files/list-media-files"},{"title":"Import Media","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json post /media","href":"/api-reference/media-files/import-media"},{"title":"Get Media File","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /media/{id}","href":"/api-reference/media-files/get-media-file"},{"title":"Delete Media File","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json delete /media/{id}","href":"/api-reference/media-files/delete-media-file"}]}]},{"group":"Billing \u0026 Usage","pages":[{"group":"Billing","pages":[{"title":"Get Usage","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /ledger/usage","href":"/api-reference/billing/get-usage"},{"title":"Get Usage by Initiator","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /ledger/usage/by-initiator","href":"/api-reference/billing/get-usage-by-initiator"}]},{"group":"Analytics","pages":[{"title":"Get Message Stats","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /messages/stats","href":"/api-reference/analytics/get-message-stats"}]}]},{"group":"Admin","pages":[{"group":"Sending Domains","pages":[{"title":"List Sending Domains","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/domains","href":"/api-reference/sending-domains/list-sending-domains"},{"title":"Get Sending Domain","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /email/domains/{id}","href":"/api-reference/sending-domains/get-sending-domain"}]},{"group":"Tracking Domains","pages":[{"title":"List Tracking Domains","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /tracking-domains","href":"/api-reference/tracking-domains/list-tracking-domains"}]},{"group":"Organizations","pages":[{"title":"List Organizations","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /organizations","href":"/api-reference/organizations/list-organizations"},{"title":"Get Hierarchy","deprecated":null,"version":null,"openapi":"/api-reference/openapi.json get /hierarchy","href":"/api-reference/organizations/get-hierarchy"}]}]}]}]}]},"title":"Import Contacts From A URL - Political Comms","buildId":"dpl_G8u2B2Ji9qJYF9umedjv293TxycS","deploymentId":"dpl_G8u2B2Ji9qJYF9umedjv293TxycS","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-S3ptrr-V.js","utils-CUxEJy9u.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-DavhVrxy.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-B1sOUY6E.js","snippetPresets-C-RLYOrF.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","ApiExamples-Duz18EdI.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-DPsbCc6D.js","shallow-B1dlhlOw.js","getApiPlaygroundDisplay-DvOu-BhE.js","CodeSnippet-By8wd64X.js","CodeSnippets-BxVv6TjI.js","Page-BGh0lBck.js","getPastedJson-DOAt9xJn.js","icon-BYg-qtQ2.js","MethodPill-Dtah8ZSz.js","DuplicateIcon-guWfDmh1.js","createIcon-pTGhj_hk.js","DynamicMarkdown-DpsHMHVL.js","SectionHeading-BbutQCjq.js","axios-vUo_bRtp.js","Markdown-DZ-stgDu.js","clsx-Dfme4k4V.js","lib--scc4DXi.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-CPNs0ebX.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-3JVAA-i3.js"]}