See exactly who a campaign would dial before you commit. It takes the same inputs as /contact-lists: a Google Sheet ref, or inline data holding CSV text or pasted “Name, +phone” lines. Nothing is stored or registered, so run it as often as you like. The one input it doesn’t take is an uploaded file — re-preview the upload instead.
For sheets the read is live, and the sheet must be reachable: shared as anyone-with-the-link, or read through a Google connectionId. When it isn’t, the 500 doesn’t forward Google’s reason — a wrong spreadsheet id, a missing tab, and an unshared file all look identical.
Non-empty means column detection failed. An unmapped phone column then shows up as every row invalidPhone with an empty value.
Available options:
phoneColumnNotFound,
nameColumnNotFound
{"docsConfig":{"theme":"mint","$schema":"https://leaves.mintlify.com/schema/docs.json","name":"Uplift AI API Docs","colors":{"primary":"#16A34A","light":"#07C983","dark":"#15803D"},"logo":{"light":"https://mintcdn.com/upliftai/2tcJSpA9F8g1W_V1/logo/logo.png?fit=max\u0026auto=format\u0026n=2tcJSpA9F8g1W_V1\u0026q=85\u0026s=c3823c19a41e66e704751aa27b97cde9","dark":"https://mintcdn.com/upliftai/2tcJSpA9F8g1W_V1/logo/logo.png?fit=max\u0026auto=format\u0026n=2tcJSpA9F8g1W_V1\u0026q=85\u0026s=c3823c19a41e66e704751aa27b97cde9"},"favicon":"https://mintcdn.com/upliftai/2tcJSpA9F8g1W_V1/favicon.ico?fit=max\u0026auto=format\u0026n=2tcJSpA9F8g1W_V1\u0026q=85\u0026s=a680f5e0b8dc59015e866648796975b1","appearance":{"default":"light","strict":true},"navbar":{"links":[{"href":"mailto:founders@upliftai.org","label":"Support"}],"primary":{"type":"button","label":"Sign Up","href":"https://upliftai.org"}},"footer":{"socials":{"linkedin":"https://www.linkedin.com/company/upliftai"}},"integrations":{"posthog":{"apiKey":"phc_EGK5H7jrhZrIhLXWfAWCmjjljJQwF6ejp1P73EtmG7q","apiHost":"https://us.i.posthog.com"}},"contextual":{"options":["copy","view","chatgpt","claude"],"display":"header"},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"upliftai","hasAudioNarration":false,"actualSubdomain":"upliftai","customDomains":["docs.upliftai.org"],"gitSource":{"type":"github","owner":"uplift-initiative","repo":"runtime-api-mintlify-docs","deployBranch":"main","contentDirectory":"","isPrivate":true,"mountPath":"","label":""},"entitlements":{},"buildId":"6ae19c28ba4b20fd94ecdb26","clientVersion":"0.0.4102","searchFilterCounts":[{"language":"default","tag":"Voice Agents","count":81},{"language":"default","tag":"API Reference","count":51},{"language":"default","tag":"Orator API","count":25},{"language":"default","tag":"SDKs","count":18},{"language":"default","tag":"Assistants","count":16},{"language":"default","tag":"Campaigns","count":11},{"language":"default","tag":"Contacts","count":11},{"language":"default","tag":"Orator REST API","count":9},{"language":"default","tag":"Node.js SDK","count":8},{"language":"default","tag":"Campaign outcomes","count":7}]},"assistantConfig":{},"basePath":"","hasChatPermissions":false,"hasWebMcpPermissions":false,"toggles":[],"googleFontsInlined":false},"customCss":[{"filePath":"style.css","content":".urdu{font-family:'Noto Nastaliq Urdu', sans-serif;font-size:1.2em;line-height:1.5em;text-align:justify;direction:rtl;unicode-bidi:embed;font-weight:normal;font-style:normal;font-variant:normal;text-transform:none}"}],"page":{"pagePath":"api-reference/contacts/dry-run-a-contact-import","slug":"/api-reference/contacts/dry-run-a-contact-import","pageMetadata":{"title":"Dry-run a contact import","description":"See exactly who a campaign would dial before you commit. It takes the same inputs as [`/contact-lists`](/api-reference/contacts/create-a-contact-list): a Google Sheet `ref`, or inline `data` holding CSV text or pasted \"Name, +phone\" lines. Nothing is stored or registered, so run it as often as you like. The one input it doesn't take is an uploaded file — [re-preview the upload](/api-reference/contacts/re-preview-an-upload-with-a-mapping) instead.\n\nFor sheets the read is live, and the sheet must be reachable: shared as anyone-with-the-link, or read through a Google `connectionId`. When it isn't, the 500 doesn't forward Google's reason — a wrong spreadsheet id, a missing tab, and an unshared file all look identical.\n\nAlready registered the source? [Re-check it](/api-reference/google-sheet-sources/re-check-a-registered-sheet) with the stored mapping instead. Column naming rules: [Special column names](/voice-agents/campaigns/contacts#special-column-names).","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /contact-sources/preview","href":"/api-reference/contacts/dry-run-a-contact-import","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 a: \"a\",\n code: \"code\",\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"See exactly who a campaign would dial before you commit. It takes the same inputs as \", _jsx(_components.a, {\n href: \"/api-reference/contacts/create-a-contact-list\",\n children: _jsx(_components.code, {\n children: \"/contact-lists\"\n })\n }), \": a Google Sheet \", _jsx(_components.code, {\n children: \"ref\"\n }), \", or inline \", _jsx(_components.code, {\n children: \"data\"\n }), \" holding CSV text or pasted “Name, +phone” lines. Nothing is stored or registered, so run it as often as you like. The one input it doesn’t take is an uploaded file — \", _jsx(_components.a, {\n href: \"/api-reference/contacts/re-preview-an-upload-with-a-mapping\",\n children: \"re-preview the upload\"\n }), \" instead.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"For sheets the read is live, and the sheet must be reachable: shared as anyone-with-the-link, or read through a Google \", _jsx(_components.code, {\n children: \"connectionId\"\n }), \". When it isn’t, the 500 doesn’t forward Google’s reason — a wrong spreadsheet id, a missing tab, and an unshared file all look identical.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Already registered the source? \", _jsx(_components.a, {\n href: \"/api-reference/google-sheet-sources/re-check-a-registered-sheet\",\n children: \"Re-check it\"\n }), \" with the stored mapping instead. Column naming rules: \", _jsx(_components.a, {\n href: \"/voice-agents/campaigns/contacts#special-column-names\",\n children: \"Special column names\"\n }), \".\"]\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":"Dry-run a contact import","description":"See exactly who a campaign would dial before you commit. It takes the same inputs as [`/contact-lists`](/api-reference/contacts/create-a-contact-list): a Google Sheet `ref`, or inline `data` holding CSV text or pasted \"Name, +phone\" lines. Nothing is stored or registered, so run it as often as you like. The one input it doesn't take is an uploaded file — [re-preview the upload](/api-reference/contacts/re-preview-an-upload-with-a-mapping) instead.\n\nFor sheets the read is live, and the sheet must be reachable: shared as anyone-with-the-link, or read through a Google `connectionId`. When it isn't, the 500 doesn't forward Google's reason — a wrong spreadsheet id, a missing tab, and an unshared file all look identical.\n\nAlready registered the source? [Re-check it](/api-reference/google-sheet-sources/re-check-a-registered-sheet) with the stored mapping instead. Column naming rules: [Special column names](/voice-agents/campaigns/contacts#special-column-names).","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /contact-sources/preview","href":"/api-reference/contacts/dry-run-a-contact-import","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":["/_mintlify/custom/upliftai/ed1a602c792dd94e/data/voices.js"],"openApiReferenceData":{"operation":{"operationId":"previewContactSource","tags":["Contacts"],"summary":"Dry-run a contact import","description":"See exactly who a campaign would dial before you commit. It takes the same inputs as [`/contact-lists`](/api-reference/contacts/create-a-contact-list): a Google Sheet `ref`, or inline `data` holding CSV text or pasted \"Name, +phone\" lines. Nothing is stored or registered, so run it as often as you like. The one input it doesn't take is an uploaded file — [re-preview the upload](/api-reference/contacts/re-preview-an-upload-with-a-mapping) instead.\n\nFor sheets the read is live, and the sheet must be reachable: shared as anyone-with-the-link, or read through a Google `connectionId`. When it isn't, the 500 doesn't forward Google's reason — a wrong spreadsheet id, a missing tab, and an unshared file all look identical.\n\nAlready registered the source? [Re-check it](/api-reference/google-sheet-sources/re-check-a-registered-sheet) with the stored mapping instead. Column naming rules: [Special column names](/voice-agents/campaigns/contacts#special-column-names).","requestBody":"f7233f3a-5636-410b-9ae5-cb77fbb51867","responses":{"200":"a678de09-55ab-42dc-988e-55d3a903dd8a","400":"91b67a15-e87b-45d3-9ee8-d3b1fa163e19","401":"4217700f-5a9a-43a7-bc79-6b8ac8a12443","403":"cbcf3e1f-da9a-42cb-836d-3af746dc49a4","404":"529c3e7e-228d-4c30-b962-62cf898fefcf","500":"fa610514-9b83-482b-80e7-0d6a25363769"},"method":"post","type":"path","servers":["f8e1e33f-9cf0-4bbb-b41e-9136c129f7ef"],"security":["73bac4ee-98c5-4fa2-834c-9f180d41c637"],"path":"/contact-sources/preview","baseUrlOptions":["https://api.upliftai.org/v1"],"title":"Dry-run a contact import","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{},"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","title":"Google Sheet","required":["kind","ref"],"properties":{"kind":{"type":"string","enum":["google_sheets"],"isRequired":true,"uniqueKey":"oneOf.0.kind","typeLabel":"enum\u003cstring>"},"ref":{"type":"string","description":"The spreadsheet id, optionally followed by `!` and a tab or A1 range (`{id}!Contacts!A:E`). A bare id reads the first tab, columns A–ZZ.","isRequired":true,"uniqueKey":"oneOf.0.ref","typeLabel":"string"},"connectionId":{"type":"string","description":"Reads through this Google connection instead of the public-link path.","uniqueKey":"oneOf.0.connectionId","typeLabel":"string"},"mapping":{"type":"object","description":"Overrides column auto-detection.","properties":{"nameColumn":{"type":"string","description":"Header name (case-insensitive) or A1 column letter. An explicit value never falls back to auto-detection — if it matches no column, names read as empty and the preview reports it in `mappingIssues`.","example":"Name","uniqueKey":"oneOf.0.mapping.nameColumn","typeLabel":"string"},"phoneColumn":{"type":"string","description":"Header name or A1 column letter, resolved like `nameColumn`.","example":"B","uniqueKey":"oneOf.0.mapping.phoneColumn","typeLabel":"string"},"attributeColumns":{"type":"array","items":{"type":"string","uniqueKey":"oneOf.0.mapping.attributeColumns.items.[INDEX]","typeLabel":"string"},"description":"Columns to carry as per-contact attributes, usable as personalization variables. Exact header names only — no A1 letters. Omit to keep every column that is not the name or phone column; send `[]` to keep none.","example":["City","Appointment"],"uniqueKey":"oneOf.0.mapping.attributeColumns","typeLabel":"string[]"}},"uniqueKey":"oneOf.0.mapping","typeLabel":"object"}},"uniqueKey":"oneOf.0","typeLabel":"Google Sheet · object"},{"type":"object","title":"Inline CSV or pasted rows","required":["kind","data"],"properties":{"kind":{"type":"string","enum":["csv_upload","paste"],"description":"`csv_upload` for CSV text with a header row; `paste` for a grid or one-line-per-contact rows.","isRequired":true,"uniqueKey":"oneOf.1.kind","typeLabel":"enum\u003cstring>"},"data":{"type":"string","description":"The rows themselves: CSV text for `csv_upload`; for `paste`, a tab/comma-separated grid or one `Name, +92…` per line.","isRequired":true,"uniqueKey":"oneOf.1.data","typeLabel":"string"},"mapping":{"type":"object","description":"Overrides column auto-detection.","properties":{"nameColumn":{"type":"string","description":"Header name (case-insensitive) or A1 column letter. An explicit value never falls back to auto-detection — if it matches no column, names read as empty and the preview reports it in `mappingIssues`.","example":"Name","uniqueKey":"oneOf.1.mapping.nameColumn","typeLabel":"string"},"phoneColumn":{"type":"string","description":"Header name or A1 column letter, resolved like `nameColumn`.","example":"B","uniqueKey":"oneOf.1.mapping.phoneColumn","typeLabel":"string"},"attributeColumns":{"type":"array","items":{"type":"string","uniqueKey":"oneOf.1.mapping.attributeColumns.items.[INDEX]","typeLabel":"string"},"description":"Columns to carry as per-contact attributes, usable as personalization variables. Exact header names only — no A1 letters. Omit to keep every column that is not the name or phone column; send `[]` to keep none.","example":["City","Appointment"],"uniqueKey":"oneOf.1.mapping.attributeColumns","typeLabel":"string[]"}},"uniqueKey":"oneOf.1.mapping","typeLabel":"object"}},"uniqueKey":"oneOf.1","typeLabel":"Inline CSV or pasted rows · object"}],"uniqueKey":"","typeLabel":"Google Sheet · object | Inline CSV or pasted rows · object"},"examples":{"sheet":{"title":"sheet","value":{"kind":"google_sheets","ref":"1kQ7bP2xLd9xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx!Contacts!A:E"}},"paste":{"title":"paste","value":{"kind":"paste","data":"عائشہ صدیقی, +923001234567\nبلال احمد, 03214567890"}}},"exampleType":"examples"}},"exampleType":"examples"},"responses":{"a678de09-55ab-42dc-988e-55d3a903dd8a":{"description":"The sheet as it stands right now. `willBeCalled` plus every count in `excluded` reconciles to `total`.","content":{"application/json":{"schema":{"type":"object","properties":{"summary":{"type":"object","description":"What the import kept and dropped.","properties":{"willBeCalled":{"type":"integer","description":"Rows that became contacts.","uniqueKey":"summary.willBeCalled","typeLabel":"integer"},"excluded":{"type":"object","description":"Dropped rows by reason. `dnc` and `recentlyCalled` are always `0` — those checks do not run yet.","properties":{"invalidPhone":{"type":"integer","uniqueKey":"summary.excluded.invalidPhone","typeLabel":"integer"},"missingName":{"type":"integer","uniqueKey":"summary.excluded.missingName","typeLabel":"integer"},"duplicate":{"type":"integer","description":"Same number seen twice. Numbers are compared as E.164, so `03001234567` and `+923001234567` collapse to one contact, keeping the first spelling.","uniqueKey":"summary.excluded.duplicate","typeLabel":"integer"},"dnc":{"type":"integer","uniqueKey":"summary.excluded.dnc","typeLabel":"integer"},"recentlyCalled":{"type":"integer","uniqueKey":"summary.excluded.recentlyCalled","typeLabel":"integer"}},"uniqueKey":"summary.excluded","typeLabel":"object"},"errors":{"type":"array","description":"The dropped rows, first 20 only.","items":{"type":"object","properties":{"row":{"type":"integer","description":"Line in the source file, counting the header as line 1.","uniqueKey":"summary.errors.items.[INDEX].row","typeLabel":"integer"},"issue":{"type":"string","enum":["invalidPhone","missingName","duplicate","dnc","recentlyCalled"],"uniqueKey":"summary.errors.items.[INDEX].issue","typeLabel":"enum\u003cstring>"},"value":{"type":"string","description":"The row's phone number: raw source text for `invalidPhone` and `missingName`, normalized for `duplicate`.","uniqueKey":"summary.errors.items.[INDEX].value","typeLabel":"string"}},"uniqueKey":"summary.errors.items.[INDEX]","typeLabel":"object"},"uniqueKey":"summary.errors","typeLabel":"object[]"}},"uniqueKey":"summary","typeLabel":"object"},"detectedMapping":{"type":"object","description":"The columns actually used, after applying `mapping`. When a name was joined from two columns, `nameColumn` reads `First Name + Last Name`.","properties":{"nameColumn":{"type":"string","description":"Header name (case-insensitive) or A1 column letter. An explicit value never falls back to auto-detection — if it matches no column, names read as empty and the preview reports it in `mappingIssues`.","example":"Name","uniqueKey":"detectedMapping.nameColumn","typeLabel":"string"},"phoneColumn":{"type":"string","description":"Header name or A1 column letter, resolved like `nameColumn`.","example":"B","uniqueKey":"detectedMapping.phoneColumn","typeLabel":"string"},"attributeColumns":{"type":"array","items":{"type":"string","uniqueKey":"detectedMapping.attributeColumns.items.[INDEX]","typeLabel":"string"},"description":"Columns to carry as per-contact attributes, usable as personalization variables. Exact header names only — no A1 letters. Omit to keep every column that is not the name or phone column; send `[]` to keep none.","example":["City","Appointment"],"uniqueKey":"detectedMapping.attributeColumns","typeLabel":"string[]"}},"uniqueKey":"detectedMapping","typeLabel":"object"},"sample":{"type":"array","maxItems":10,"description":"The first ten contacts that would be dialed.","items":{"type":"object","properties":{"name":{"type":"string","uniqueKey":"sample.items.[INDEX].name","typeLabel":"string"},"phone":{"type":"string","description":"Kept in the format the sheet used, PK national (`03…`) or E.164 (`+92…`), with spaces and dashes stripped.","uniqueKey":"sample.items.[INDEX].phone","typeLabel":"string"},"attributes":{"type":"object","additionalProperties":{"type":"string","uniqueKey":"sample.items.[INDEX].attributes.additionalProperties","typeLabel":"string"},"description":"The remaining columns, handed to the assistant as a contact record at dial time. Truncated at 1500 bytes per contact.","uniqueKey":"sample.items.[INDEX].attributes","typeLabel":"object"}},"uniqueKey":"sample.items.[INDEX]","typeLabel":"object"},"uniqueKey":"sample","typeLabel":"object[]"},"total":{"type":"integer","description":"Rows read, before validation.","uniqueKey":"total","typeLabel":"integer"},"columns":{"type":"array","items":{"type":"string","uniqueKey":"columns.items.[INDEX]","typeLabel":"string"},"description":"The header row as parsed — what a `mapping` override chooses from. Absent for free-form paste, which has no headers.","uniqueKey":"columns","typeLabel":"string[]"},"mappingIssues":{"type":"array","items":{"type":"string","enum":["phoneColumnNotFound","nameColumnNotFound"],"uniqueKey":"mappingIssues.items.[INDEX]","typeLabel":"enum\u003cstring>"},"description":"Non-empty means column detection failed. An unmapped phone column then shows up as every row `invalidPhone` with an empty value.","uniqueKey":"mappingIssues","typeLabel":"enum\u003cstring>[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"detected":{"title":"detected","value":{"summary":{"willBeCalled":3,"excluded":{"invalidPhone":1,"missingName":0,"duplicate":1,"dnc":0,"recentlyCalled":0},"errors":[{"row":4,"issue":"duplicate","value":"03001234567"},{"row":5,"issue":"invalidPhone","value":"0345"}]},"detectedMapping":{"nameColumn":"Name","phoneColumn":"Mobile No.","attributeColumns":["City","Policy Amount","Due Date"]},"sample":[{"name":"عائشہ صدیقی","phone":"+923001234567","attributes":{"City":"لاہور","Policy Amount":"Rs 18,000","Due Date":"25 اگست"}},{"name":"بلال احمد","phone":"03211234567","attributes":{"City":"کراچی","Policy Amount":"Rs 42,500","Due Date":"27 اگست"}},{"name":"حمزہ شیخ","phone":"+923339876543","attributes":{"City":"ملتان","Policy Amount":"Rs 30,000","Due Date":"30 اگست"}}],"total":5,"columns":["Name","Mobile No.","City","Policy Amount","Due Date"],"mappingIssues":[]}},"phoneColumnMissing":{"title":"phoneColumnMissing","value":{"summary":{"willBeCalled":0,"excluded":{"invalidPhone":2,"missingName":0,"duplicate":0,"dnc":0,"recentlyCalled":0},"errors":[{"row":2,"issue":"invalidPhone","value":""},{"row":3,"issue":"invalidPhone","value":""}]},"detectedMapping":{"nameColumn":"Full Name","attributeColumns":["Mobile Number Updated","Branch"]},"sample":[],"total":2,"columns":["Full Name","Mobile Number Updated","Branch"],"mappingIssues":["phoneColumnNotFound"]}}},"exampleType":"examples"}},"exampleType":"examples"},"91b67a15-e87b-45d3-9ee8-d3b1fa163e19":{"description":"The request can't be resolved to rows — `ref` missing on a `google_sheets` preview, `data` missing on a `csv_upload` or `paste`, `connectionId` sent with a non-sheet kind, or `kind` outside the enum.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"oneOf":[{"type":"string","description":"One message per failed field for validation errors, a single string otherwise.","uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"One message per failed field for validation errors, a single string otherwise.","uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","uniqueKey":"error","typeLabel":"string"},"statusCode":{"type":"integer","uniqueKey":"statusCode","typeLabel":"integer"}},"uniqueKey":"","typeLabel":"object"},"example":{"message":"google_sheets requires `ref`","error":"Bad Request","statusCode":400},"examples":{"Example":{"title":"Example","value":{"message":"google_sheets requires `ref`","error":"Bad Request","statusCode":400}}},"exampleType":"examples"}},"exampleType":"examples"},"4217700f-5a9a-43a7-bc79-6b8ac8a12443":{"description":"A bearer key was sent but is not recognized.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"oneOf":[{"type":"string","description":"One message per failed field for validation errors, a single string otherwise.","uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"One message per failed field for validation errors, a single string otherwise.","uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","uniqueKey":"error","typeLabel":"string"},"statusCode":{"type":"integer","uniqueKey":"statusCode","typeLabel":"integer"}},"uniqueKey":"","typeLabel":"object"},"example":{"message":"invalid authorization","error":"Unauthorized","statusCode":401},"examples":{"Example":{"title":"Example","value":{"message":"invalid authorization","error":"Unauthorized","statusCode":401}}},"exampleType":"examples"}},"exampleType":"examples"},"cbcf3e1f-da9a-42cb-836d-3af746dc49a4":{"description":"No API key sent, or the key lacks permission for this resource.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"oneOf":[{"type":"string","description":"One message per failed field for validation errors, a single string otherwise.","uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"One message per failed field for validation errors, a single string otherwise.","uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","uniqueKey":"error","typeLabel":"string"},"statusCode":{"type":"integer","uniqueKey":"statusCode","typeLabel":"integer"}},"uniqueKey":"","typeLabel":"object"},"example":{"message":"Forbidden resource","error":"Forbidden","statusCode":403},"examples":{"Example":{"title":"Example","value":{"message":"Forbidden resource","error":"Forbidden","statusCode":403}}},"exampleType":"examples"}},"exampleType":"examples"},"529c3e7e-228d-4c30-b962-62cf898fefcf":{"description":"No connection under that `connectionId` in this project.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"oneOf":[{"type":"string","description":"One message per failed field for validation errors, a single string otherwise.","uniqueKey":"message.oneOf.0","typeLabel":"string"},{"type":"array","items":{"type":"string","uniqueKey":"message.oneOf.1.items.[INDEX]","typeLabel":"string"},"description":"One message per failed field for validation errors, a single string otherwise.","uniqueKey":"message.oneOf.1","typeLabel":"string[]"}],"uniqueKey":"message","typeLabel":"string | string[]"},"error":{"type":"string","uniqueKey":"error","typeLabel":"string"},"statusCode":{"type":"integer","uniqueKey":"statusCode","typeLabel":"integer"}},"uniqueKey":"","typeLabel":"object"},"example":{"message":"Connection not found: 6f3d9a52-xxxx-xxxx-xxxx-xxxxxxxxxxxx","error":"Not Found","statusCode":404},"examples":{"Example":{"title":"Example","value":{"message":"Connection not found: 6f3d9a52-xxxx-xxxx-xxxx-xxxxxxxxxxxx","error":"Not Found","statusCode":404}}},"exampleType":"examples"}},"exampleType":"examples"},"fa610514-9b83-482b-80e7-0d6a25363769":{"description":"The sheet could not be read: wrong spreadsheet id, no such tab, or it isn't shared with the platform. Google's own error is not forwarded.","content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","uniqueKey":"message","typeLabel":"string"},"statusCode":{"type":"integer","uniqueKey":"statusCode","typeLabel":"integer"}},"uniqueKey":"","typeLabel":"object"},"example":{"statusCode":500,"message":"Internal server error"},"examples":{"Example":{"title":"Example","value":{"statusCode":500,"message":"Internal server error"}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{"73bac4ee-98c5-4fa2-834c-9f180d41c637":{"apiKey":{"type":"http","scheme":"bearer","description":"Project API key (`sk_api_…`).","scopes":[],"schemeName":"apiKey"}}},"servers":{"f8e1e33f-9cf0-4bbb-b41e-9136c129f7ef":{"url":"https://api.upliftai.org/v1"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","description":"Project API key (`sk_api_…`).","scopes":[],"schemeName":"apiKey"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Project API key (`sk_api_…`).","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"apiKey","name":"Authorization"}],"title":"apiKey"}]},"originalFileLocation":"voice-agents/api-reference/openapi.yaml"},"subdomain":"upliftai","siteName":"Uplift AI API Docs","title":"Dry-run a contact import - Uplift AI API Docs","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-10-28T06:54:41.369Z","originalFileLocation":"api-reference/contacts/dry-run-a-contact-import.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=\"light\";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=\"light\"}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=\"See exactly who a campaign would dial before you commit. It takes the same inputs as /contact-lists: a Google Sheet ref, or inline data holding CSV text or pasted \u0026quot;Name, +phone\u0026quot; lines. Nothing is stored or registered, so run it as often as you like. The one input it doesn\u0026#x27;t take is an uploaded file — re-preview the upload instead. For sheets the read is live, and the sheet must be reachable: shared as anyone-with-the-link, or read through a Google connectionId. When it isn\u0026#x27;t, the 500 doesn\u0026#x27;t forward Google\u0026#x27;s reason — a wrong spreadsheet id, a missing tab, and an unshared file all look identical. Already registered the source? Re-check it with the stored mapping instead. Column naming rules: Special column names.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Uplift AI API Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/upliftai/JKzTglt2sBZGZsC-/_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/upliftai/JKzTglt2sBZGZsC-/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/upliftai/JKzTglt2sBZGZsC-/_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/upliftai/JKzTglt2sBZGZsC-/_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/upliftai/JKzTglt2sBZGZsC-/_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/upliftai/JKzTglt2sBZGZsC-/_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/upliftai/JKzTglt2sBZGZsC-/_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/upliftai/JKzTglt2sBZGZsC-/_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/upliftai/JKzTglt2sBZGZsC-/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Dry-run a contact import - Uplift AI API Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"See exactly who a campaign would dial before you commit. It takes the same inputs as /contact-lists: a Google Sheet ref, or inline data holding CSV text or pasted \u0026quot;Name, +phone\u0026quot; lines. Nothing is stored or registered, so run it as often as you like. The one input it doesn\u0026#x27;t take is an uploaded file — re-preview the upload instead. For sheets the read is live, and the sheet must be reachable: shared as anyone-with-the-link, or read through a Google connectionId. When it isn\u0026#x27;t, the 500 doesn\u0026#x27;t forward Google\u0026#x27;s reason — a wrong spreadsheet id, a missing tab, and an unshared file all look identical. Already registered the source? Re-check it with the stored mapping instead. Column naming rules: Special column names.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Uplift AI API Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.upliftai.org/api-reference/contacts/dry-run-a-contact-import\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://upliftai.mintlify.site/_mintlify/api/og/v2?division=Contacts\u0026amp;title=Dry-run+a+contact+import\u0026amp;description=See+exactly+who+a+campaign+would+dial+before+you+commit.+It+takes+the+same+inputs+as+%5B%60%2Fcontact-lists%60%5D%28%2Fapi-reference%2Fcontacts%2Fcreate-a-contact-list%29%3A+a+Google\u0026amp;theme=bb6dd6d40a49e0d34c2227da\u0026amp;signature=442025ddf6bba48e78543b69f16f074ff70e11875f896c2ebf81ad0af7f8ea6f\">\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=\"Dry-run a contact import - Uplift AI API Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"See exactly who a campaign would dial before you commit. It takes the same inputs as /contact-lists: a Google Sheet ref, or inline data holding CSV text or pasted \u0026quot;Name, +phone\u0026quot; lines. Nothing is stored or registered, so run it as often as you like. The one input it doesn\u0026#x27;t take is an uploaded file — re-preview the upload instead. For sheets the read is live, and the sheet must be reachable: shared as anyone-with-the-link, or read through a Google connectionId. When it isn\u0026#x27;t, the 500 doesn\u0026#x27;t forward Google\u0026#x27;s reason — a wrong spreadsheet id, a missing tab, and an unshared file all look identical. Already registered the source? Re-check it with the stored mapping instead. Column naming rules: Special column names.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://upliftai.mintlify.site/_mintlify/api/og/v2?division=Contacts\u0026amp;title=Dry-run+a+contact+import\u0026amp;description=See+exactly+who+a+campaign+would+dial+before+you+commit.+It+takes+the+same+inputs+as+%5B%60%2Fcontact-lists%60%5D%28%2Fapi-reference%2Fcontacts%2Fcreate-a-contact-list%29%3A+a+Google\u0026amp;theme=bb6dd6d40a49e0d34c2227da\u0026amp;signature=442025ddf6bba48e78543b69f16f074ff70e11875f896c2ebf81ad0af7f8ea6f\">\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/upliftai/JKzTglt2sBZGZsC-/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Uplift AI API Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#16A34A\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.upliftai.org/api-reference/contacts/dry-run-a-contact-import\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/contacts/dry-run-a-contact-import.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.upliftai.org/#organization\",\"name\":\"Uplift AI API Docs\",\"url\":\"https://docs.upliftai.org\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/upliftai/2tcJSpA9F8g1W_V1/logo/logo.png?fit=max\u0026auto=format\u0026n=2tcJSpA9F8g1W_V1\u0026q=85\u0026s=c3823c19a41e66e704751aa27b97cde9\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.upliftai.org#website\",\"name\":\"Uplift AI API Docs\",\"url\":\"https://docs.upliftai.org\",\"publisher\":{\"@id\":\"https://docs.upliftai.org/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.upliftai.org/api-reference/contacts/dry-run-a-contact-import#webpage\",\"url\":\"https://docs.upliftai.org/api-reference/contacts/dry-run-a-contact-import\",\"name\":\"Dry-run a contact import\",\"description\":\"See exactly who a campaign would dial before you commit. It takes the same inputs as /contact-lists: a Google Sheet ref, or inline data holding CSV text or pasted \\\"Name, +phone\\\" lines. Nothing is stored or registered, so run it as often as you like. The one input it doesn't take is an uploaded file — re-preview the upload instead. For sheets the read is live, and the sheet must be reachable: shared as anyone-with-the-link, or read through a Google connectionId. When it isn't, the 500 doesn't forward Google's reason — a wrong spreadsheet id, a missing tab, and an unshared file all look identical. Already registered the source? Re-check it with the stored mapping instead. Column naming rules: Special column names.\",\"dateModified\":\"2026-10-28T06:54:41.369Z\",\"isPartOf\":{\"@id\":\"https://docs.upliftai.org#website\"},\"breadcrumb\":{\"@id\":\"https://docs.upliftai.org/api-reference/contacts/dry-run-a-contact-import#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.upliftai.org/api-reference/contacts/dry-run-a-contact-import#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"API Reference\",\"item\":\"https://docs.upliftai.org/voice-agents/api-reference/limits\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Contacts\",\"item\":\"https://docs.upliftai.org/api-reference/contacts/upload-a-contact-file\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Dry-run a contact import\",\"item\":\"https://docs.upliftai.org/api-reference/contacts/dry-run-a-contact-import\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.upliftai.org/api-reference/contacts/dry-run-a-contact-import#apireference\",\"headline\":\"Dry-run a contact import\",\"name\":\"Dry-run a contact import\",\"description\":\"See exactly who a campaign would dial before you commit. It takes the same inputs as /contact-lists: a Google Sheet ref, or inline data holding CSV text or pasted \\\"Name, +phone\\\" lines. Nothing is stored or registered, so run it as often as you like. The one input it doesn't take is an uploaded file — re-preview the upload instead. For sheets the read is live, and the sheet must be reachable: shared as anyone-with-the-link, or read through a Google connectionId. When it isn't, the 500 doesn't forward Google's reason — a wrong spreadsheet id, a missing tab, and an unshared file all look identical. Already registered the source? Re-check it with the stored mapping instead. Column naming rules: Special column names.\",\"url\":\"https://docs.upliftai.org/api-reference/contacts/dry-run-a-contact-import\",\"mainEntityOfPage\":{\"@id\":\"https://docs.upliftai.org/api-reference/contacts/dry-run-a-contact-import#webpage\"},\"dateModified\":\"2026-10-28T06:54:41.369Z\",\"publisher\":{\"@id\":\"https://docs.upliftai.org/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.upliftai.org#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Uplift AI API Docs\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Uplift AI API Docs\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/api-reference/contacts/dry-run-a-contact-import.md","siteName":"Uplift AI API Docs","nav":{"global":null,"tabs":[{"tab":"Orator API","pages":[{"title":"Orator API","href":"/introduction"}]},{"tab":"Voice Agents","groups":[{"group":"Getting started","pages":[{"title":"Overview","href":"/voice-agents/getting-started/overview"},{"title":"Quickstart: Web","href":"/voice-agents/getting-started/quickstart-web"},{"title":"Quickstart: Phone","href":"/voice-agents/getting-started/quickstart-phone"}]},{"group":"Concepts","pages":[{"title":"How it works","href":"/voice-agents/concepts/how-it-works"},{"title":"Tools overview","href":"/voice-agents/concepts/tools-overview"},{"title":"Phone call states","href":"/voice-agents/concepts/phone-call-states"},{"title":"Pricing","href":"/voice-agents/concepts/pricing"}]},{"group":"Assistants","pages":[{"title":"Working with assistants","href":"/voice-agents/assistants/working-with-assistants"},{"title":"Draft and publish","href":"/voice-agents/assistants/versions"},{"title":"Transient vs stored assistants","href":"/voice-agents/assistants/transient-vs-stored"},{"title":"Provider \u0026 model reference","href":"/voice-agents/assistants/providers-and-models"},{"title":"Recommended stack","href":"/voice-agents/assistants/recommended-stack"},{"title":"Voice prompting","href":"/voice-agents/assistants/voice-prompting"},{"title":"Build, refine \u0026 simulate","href":"/voice-agents/assistants/build-refine-simulate"},{"title":"Scorecards","href":"/voice-agents/assistants/scorecards"}]},{"group":"Tools","pages":[{"title":"Client tools","href":"/voice-agents/tools/client-tools"},{"title":"Webhook tools","href":"/voice-agents/tools/webhook-tools"},{"title":"End call","href":"/voice-agents/tools/system/end-call"}]},{"group":"Personalization","pages":[{"title":"Variables","href":"/voice-agents/personalization/variables"},{"title":"Per-call instructions","href":"/voice-agents/personalization/per-call-instructions"}]},{"group":"Calling","pages":[{"title":"Outbound calls","href":"/voice-agents/calling/outbound"},{"title":"Inbound calls","href":"/voice-agents/calling/inbound"},{"title":"Phone numbers \u0026 concurrency","href":"/voice-agents/calling/concurrency"},{"title":"Call end reasons","href":"/voice-agents/calling/call-end-reasons"},{"title":"Session details \u0026 transcripts","href":"/voice-agents/calling/session-details"},{"title":"Live listen","href":"/voice-agents/calling/live-listen"}]},{"group":"Campaigns","pages":[{"title":"Getting started with batch calling","href":"/voice-agents/campaigns/getting-started"},{"title":"[ ] Static vs continuous campaigns","hidden":true,"href":"/voice-agents/campaigns/static-vs-continuous"},{"title":"[ ] Static campaigns","hidden":true,"href":"/voice-agents/campaigns/static"},{"title":"[ ] Continuous campaigns","hidden":true,"href":"/voice-agents/campaigns/continuous"},{"title":"[ ] Contacts","hidden":true,"href":"/voice-agents/campaigns/contacts"},{"title":"[ ] Scheduling \u0026 retries","hidden":true,"href":"/voice-agents/campaigns/scheduling-and-retries"},{"title":"[ ] Goals \u0026 scorecards","hidden":true,"href":"/voice-agents/campaigns/goals-and-scorecards"},{"title":"[ ] Results \u0026 stats","hidden":true,"href":"/voice-agents/campaigns/results"}]},{"group":"Webhooks","pages":[{"title":"Webhooks","href":"/voice-agents/webhooks/overview"},{"title":"Event reference","href":"/voice-agents/webhooks/events"}]},{"group":"Frontend","pages":[{"title":"[ ] Architecture","hidden":true,"href":"/voice-agents/frontend/architecture"},{"title":"[ ] React","hidden":true,"href":"/voice-agents/frontend/react"},{"title":"[ ] Widget embed","hidden":true,"href":"/voice-agents/frontend/widget"},{"title":"[ ] Monitoring UI","hidden":true,"href":"/voice-agents/frontend/monitoring-ui"}]},{"group":"Testing","pages":[{"title":"Simulating conversations","href":"/voice-agents/testing/simulation"}]},{"group":"Guides","pages":[{"title":"[ ] Appointment scheduling","hidden":true,"href":"/voice-agents/guides/appointment-scheduling"},{"title":"[ ] Event invitation","hidden":true,"href":"/voice-agents/guides/event-invitation"},{"title":"[ ] Sales / lead qualification","hidden":true,"href":"/voice-agents/guides/lead-qualification"},{"title":"[ ] Payment reminder","hidden":true,"href":"/voice-agents/guides/payment-reminder"},{"title":"[ ] Order confirmation","hidden":true,"href":"/voice-agents/guides/order-confirmation"}]},{"group":"API Reference","pages":[{"title":"Phone numbers \u0026 limits","href":"/voice-agents/api-reference/limits"},{"group":"Assistants","pages":[{"title":"Create an assistant","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /realtime-assistants","href":"/api-reference/assistants/create-an-assistant"},{"title":"List assistants","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /realtime-assistants","href":"/api-reference/assistants/list-assistants"},{"title":"Get an assistant","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /realtime-assistants/{realtimeAssistantId}","href":"/api-reference/assistants/get-an-assistant"},{"title":"Update an assistant","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /realtime-assistants/{realtimeAssistantId}","href":"/api-reference/assistants/update-an-assistant"},{"title":"Delete an assistant","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml delete /realtime-assistants/{realtimeAssistantId}","href":"/api-reference/assistants/delete-an-assistant"},{"title":"Publish an assistant version","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /realtime-assistants/{realtimeAssistantId}/publish","href":"/api-reference/assistants/publish-an-assistant-version"},{"title":"List published versions","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /realtime-assistants/{realtimeAssistantId}/versions","href":"/api-reference/assistants/list-published-versions"},{"title":"Get an assistant's publish state","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /realtime-assistants/{realtimeAssistantId}/metadata","href":"/api-reference/assistants/get-an-assistants-publish-state"}]},{"group":"Authoring an assistant","pages":[{"title":"Build an assistant from a brief","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /realtime-assistants/builds","href":"/api-reference/authoring-an-assistant/build-an-assistant-from-a-brief"},{"title":"Poll a build's progress","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /realtime-assistants/builds/status/{buildId}","href":"/api-reference/authoring-an-assistant/poll-a-builds-progress"},{"title":"Rehearse a call against a persona","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /realtime-assistants/builds/{assistantId}/simulate","href":"/api-reference/authoring-an-assistant/rehearse-a-call-against-a-persona"},{"title":"Refine a built assistant's prompt","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /realtime-assistants/builds/{assistantId}/refine","href":"/api-reference/authoring-an-assistant/refine-a-built-assistants-prompt"},{"title":"Get an assistant's build record","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /realtime-assistants/builds/{assistantId}","href":"/api-reference/authoring-an-assistant/get-an-assistants-build-record"}]},{"group":"Starting a conversation","pages":[{"title":"Create a web session token","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /realtime-assistants/{realtimeAssistantId}/session","href":"/api-reference/starting-a-conversation/create-a-web-session-token"},{"title":"Open a session without an API key","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /realtime-assistants/{realtimeAssistantId}/public-session","href":"/api-reference/starting-a-conversation/open-a-session-without-an-api-key"},{"title":"Start a session from inline config","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /realtime-assistants/adhoc/session","href":"/api-reference/starting-a-conversation/start-a-session-from-inline-config"},{"title":"Dispatch a call from this assistant","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /realtime-assistants/{realtimeAssistantId}/call","href":"/api-reference/starting-a-conversation/dispatch-a-call-from-this-assistant"}]},{"group":"Sessions \u0026 call records","pages":[{"title":"List an assistant's sessions","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /realtime-assistants/{realtimeAssistantId}/sessions","href":"/api-reference/sessions-\u0026-call-records/list-an-assistants-sessions"},{"title":"Get a session's status","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /realtime-assistants/sessions/{sessionId}","href":"/api-reference/sessions-\u0026-call-records/get-a-sessions-status"},{"title":"Get a call's transcript and outcomes","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /realtime-assistants/sessions/{sessionId}/detail","href":"/api-reference/sessions-\u0026-call-records/get-a-calls-transcript-and-outcomes"},{"title":"Listen in on a live call","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /realtime-assistants/sessions/{sessionId}/listen","href":"/api-reference/sessions-\u0026-call-records/listen-in-on-a-live-call"}]},{"group":"Campaigns","pages":[{"title":"Create a campaign","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /campaigns","href":"/api-reference/campaigns/create-a-campaign"},{"title":"List campaigns","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /campaigns","href":"/api-reference/campaigns/list-campaigns"},{"title":"Get a campaign","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /campaigns/{campaignId}","href":"/api-reference/campaigns/get-a-campaign"},{"title":"Update a campaign","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml patch /campaigns/{campaignId}","href":"/api-reference/campaigns/update-a-campaign"},{"title":"Schedule a campaign launch","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /campaigns/{campaignId}/schedule","href":"/api-reference/campaigns/schedule-a-campaign-launch"},{"title":"Launch a campaign now","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /campaigns/{campaignId}/launch","href":"/api-reference/campaigns/launch-a-campaign-now"},{"title":"Append contacts to a campaign","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /campaigns/{campaignId}/contacts","href":"/api-reference/campaigns/append-contacts-to-a-campaign"},{"title":"Pause campaign dialing","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /campaigns/{campaignId}/pause","href":"/api-reference/campaigns/pause-campaign-dialing"},{"title":"Resume a paused campaign","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /campaigns/{campaignId}/resume","href":"/api-reference/campaigns/resume-a-paused-campaign"},{"title":"Close a continuous campaign","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /campaigns/{campaignId}/close","href":"/api-reference/campaigns/close-a-continuous-campaign"}]},{"group":"Campaign outcomes","pages":[{"title":"Aggregate stats for a campaign","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /campaigns/{campaignId}/stats","href":"/api-reference/campaign-outcomes/aggregate-stats-for-a-campaign"},{"title":"List a campaign's outcomes","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /campaigns/{campaignId}/results","href":"/api-reference/campaign-outcomes/list-a-campaigns-outcomes"},{"title":"List a campaign's calls","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /campaigns/{campaignId}/calls","href":"/api-reference/campaign-outcomes/list-a-campaigns-calls"},{"title":"List a campaign's callback requests","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /campaigns/{campaignId}/callbacks","href":"/api-reference/campaign-outcomes/list-a-campaigns-callback-requests"},{"title":"Update a callback's status","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml patch /campaigns/callbacks/{callbackId}","href":"/api-reference/campaign-outcomes/update-a-callbacks-status"},{"title":"Add a note to a callback","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /campaigns/callbacks/{callbackId}/notes","href":"/api-reference/campaign-outcomes/add-a-note-to-a-callback"},{"title":"List a campaign's conversion records","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /campaigns/{campaignId}/conversions","href":"/api-reference/campaign-outcomes/list-a-campaigns-conversion-records"}]},{"group":"Contacts","pages":[{"title":"Upload a contact file","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /contact-lists/uploads","href":"/api-reference/contacts/upload-a-contact-file"},{"title":"Re-preview an upload with a mapping","description":"Try a column mapping before you commit to it. Nothing is written, so re-run this as often as you need while adjusting — a body is still required, so send `{}` to just re-run auto-detection. When the sample looks right, create the list from the same `uploadId` and mapping. Column naming rules: [Special column names](/voice-agents/campaigns/contacts#special-column-names).","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /contact-lists/uploads/{uploadId}/preview","href":"/api-reference/contacts/re-preview-an-upload-with-a-mapping"},{"title":"Dry-run a contact import","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /contact-sources/preview","href":"/api-reference/contacts/dry-run-a-contact-import"},{"title":"Create a contact list","description":"Turn rows into a stored list you can call: an upload from [`/contact-lists/uploads`](/api-reference/contacts/upload-a-contact-file), inline CSV or pasted lines, or a Google Sheet. The import validates rows and deduplicates by phone number, keeping only contacts that can be dialed. Pass the returned `listId` as a campaign's `config.contacts.listId`. A list is never edited — to call a different set of people, import again. To see the outcome before creating: [dry-run](/api-reference/contacts/dry-run-a-contact-import) inline rows or a sheet, [re-preview](/api-reference/contacts/re-preview-an-upload-with-a-mapping) an uploaded file. Column naming rules: [Special column names](/voice-agents/campaigns/contacts#special-column-names).","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /contact-lists","href":"/api-reference/contacts/create-a-contact-list"},{"title":"List contact lists","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /contact-lists","href":"/api-reference/contacts/list-contact-lists"},{"title":"Get a contact list's metadata","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /contact-lists/{listId}","href":"/api-reference/contacts/get-a-contact-lists-metadata"},{"title":"Page through a list's contacts","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /contact-lists/{listId}/contacts","href":"/api-reference/contacts/page-through-a-lists-contacts"},{"group":"Google Sheet sources","pages":[{"title":"Register a Google Sheet as a source","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /contact-sources","href":"/api-reference/google-sheet-sources/register-a-google-sheet-as-a-source"},{"title":"List registered contact sources","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /contact-sources","href":"/api-reference/google-sheet-sources/list-registered-contact-sources"},{"title":"Get a contact source's metadata","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml get /contact-sources/{sourceId}","href":"/api-reference/google-sheet-sources/get-a-contact-sources-metadata"},{"title":"Re-check a registered sheet","deprecated":null,"version":null,"openapi":"/voice-agents/api-reference/openapi.yaml post /contact-sources/{sourceId}/preview","href":"/api-reference/google-sheet-sources/re-check-a-registered-sheet"}]}]},{"group":"Integrations \u0026 delivery health","pages":[{"title":"Webhooks on the portal","href":"/voice-agents/api-reference/webhooks-on-the-portal"}]}]}]},{"tab":"Integration API","hidden":true,"pages":[{"title":"Integration API","href":"/voice-agents/api-reference/integration-api"}]},{"tab":"Realtime Assistants","hidden":true,"pages":[{"title":"Realtime Assistants","href":"/assistants/introduction"}]},{"tab":"Tutorials","pages":[{"title":"Tutorials","href":"/tutorials/livekit-voice-agent"}]},{"tab":"Syngenta Assistant","hidden":true,"pages":[{"title":"Syngenta Assistant","href":"/syngenta/authentication"}]}]},"basePath":"","title":"Dry-run a contact import - Uplift AI API Docs","buildId":"dpl_596ePT575z4qnAFksq1biRW97aLY","deploymentId":"dpl_596ePT575z4qnAFksq1biRW97aLY","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-C9Wu0MeN.js","utils-jWgu-6Qf.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-DBD8f9qn.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-BGuX1ui5.js","snippetPresets-Evy63nQB.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-BQHO1lnV.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-B6C8m-t_.js","shallow-BG4cT0fH.js","getApiPlaygroundDisplay-CgEPrE-D.js","CodeSnippet-CU8JyZ9N.js","CodeSnippets-BnxHU32T.js","Page-D6S0Yh6q.js","getPastedJson-CwiYOonh.js","icon-DYDpWmDf.js","MethodPill-C-J-l7_c.js","DuplicateIcon-B6ARwg9w.js","createIcon-Dsv4MtDq.js","DynamicMarkdown-CtasenyM.js","SectionHeading-YNcgYwjB.js","axios-vUo_bRtp.js","Markdown-CwLx6PAg.js","clsx-C3kuh_dz.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-CmKHfscc.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-U3mI6Ljh.js"]}