Book a demo

Call Ingest API

Send calls from your own dialer, meeting tool or call export into Zime, where each call gets a summary, insights and a CRM deal match.

For admins

The Call Ingest API sends calls from your own dialer, meeting tool or call export into Zime. Company admins generate the ingest key in Zime under Admin, then APIs. The questions below cover the key, the fields to send, skipped calls, resends, status checks and what you see in Zime. For the full technical reference, including request fields, errors and a sender script, see the Call Ingest API developer reference.

What the Call Ingest API does

The Call Ingest API sends calls from your own dialer, meeting tool or call export into Zime.

You post one call at a time, with its transcript, a link to its recording, or both. Zime adds the call to the rep's calls, builds its summary and insights, and maps it to a CRM deal. It does not read your calls back out, create Zime users, or take deal or CRM IDs.

The Zime REST API is the one that reads data out of Zime. The two use separate keys.

Zime REST APICall Ingest API

Direction

Reads data out of Zime

Sends calls into Zime

Key

Your API key

Your ingest key

Before you start

Three things need to be in place before you send the first call.

You need an ingest key, which a company admin generates in Zime. You need a source, which Zime registers and turns on for your company. And every rep on your calls must be an active Zime user. Until Zime turns the source on, the API answers 422 unknown_source.

Send the key in the X-API-Key header of every request. A company has one active ingest key at a time. To rotate it, press Generate new key: the old key stops working the moment the new one is created. Press Revoke to stop your company sending calls until an admin generates a new key.

  1. Open the APIs tab

    In Zime, go to Admin, then APIs. Only company admins see the APIs tab.

  2. Generate the key

    Press Generate key in the Ingest key (write) card.

  3. Keep it safe

    Keep the key in your secret store. Never send it by email or chat in plain text. Press Show key or Copy in the same card to find it again.

  4. Ask Zime to turn on your source

    Email support@zime.ai or ask your Zime contact. Name the system that will send your calls, and say whether it sends dialer calls or meetings.

Send a call

Each call is one request, with the fields below.

Write times in ISO 8601 with a time zone, for example 2026-10-19T09:43:35Z. A time without a zone returns 400 invalid_payload. A request can be up to 1 MB of JSON, sent with Content-Type: application/json.

To send a recording instead of a transcript, put an https link to the file in recording.audio_url. Zime downloads it and transcribes it. If you send the same call again with the same source and external_call_id, Zime keeps one copy and answers 200 with duplicate: true.

FieldWhat to send

source

The name of the system that sent the call. Zime registers it for your company: 2 to 40 lowercase letters, digits or underscores.

external_call_id

That system's own ID for the call: 1 to 128 letters, digits, dots, underscores, colons or hyphens.

started_at, ended_at

ISO 8601 with a time zone. ended_at cannot be before started_at, or more than 24 hours after it.

rep

The rep, with an email. Must be an active Zime user in your company.

Participants

At least one who is not the rep, with an email or a phone.

Transcript or recording

A transcript with format set to segments, a recording link, or both.

What happens after

A 202 answer means Zime has accepted the call and queued it. It has not processed it yet.

In Zime's production tests, with few calls queued, a call sent with a transcript was in Zime about 10 to 45 seconds after sending, with its summary and insights ready about 4 to 7 minutes after. A recording-only call took 1 to 3 minutes on short test recordings. These are measured times, not a guarantee, and waits grow when many calls are queued.

The call appears on the Calls page, in the Recordings tab, as a call of the rep in rep.email. Dialer calls are hidden by default: tick Dialer in the call filters to see them. Zime maps the call to a CRM deal itself, so you do not send deal IDs. To check one call, send GET /api/v1/calls/ingest/{source}/{external_call_id} with your ingest key.

StatusWhat it means

queued

Accepted and waiting.

processing

Being processed, or waiting for speech to text.

completed

The call is in Zime.

skipped

Not added. The reason says why.

failed

Could not be added. Fix the cause named in the error and resend.

Limits and errors

Zime accepts about 600 requests a minute for each key. Above that it may answer 429 rate_limited with a Retry-After header, in seconds.

Retry 429 after the number of seconds in Retry-After, and retry 500 or 503 with growing waits. Do not resend 400, 401, 403, 413 or 422 unchanged: fix the cause first. A resend never creates a second copy of a call. Your source's rules can also skip calls, and the response then says status skipped with a reason.

If you are stuck, email support@zime.ai with your company name, the source, the external_call_id and the response you got. Never send the key.

AnswerWhat to do

401 api_key_required

Send the key in the X-API-Key header. A key in the URL or in an Authorization: Bearer header is not read.

403 invalid_api_key

The key is wrong, was rotated or revoked, or is your API key rather than your ingest key.

413 payload_too_large

The request is over 1 MB. Send a smaller one.

422 unknown_source

Zime has not turned your source on yet.

422 rep_not_found or rep_inactive

Add the rep as an active Zime user, then send the call again.

429 rate_limited

Wait the seconds in Retry-After, then retry.

Questions

About the API

6 answers
What does the Call Ingest API do?

It sends calls from your own dialer, meeting tool or call export into Zime. You post one call at a time with its transcript, a link to its recording, or both. Zime adds the call to the rep's calls, builds its summary and insights, and maps it to a CRM deal.

What does it not do?

It does not read your calls, transcripts or insights: use the REST API for that. It does not create Zime users: every rep must already be an active Zime user in your company. It does not take deal or CRM IDs: Zime maps the deal itself. It does not change or delete a call once Zime has started processing it.

How is it different from the Zime REST API?

The REST API reads data out of Zime. The Call Ingest API sends calls into Zime. They share the base URL https://nodejs-overhaul-prod.zime.ai but use separate keys: your API key cannot send calls, and your ingest key cannot read calls, transcripts or insights.

Which tools can send calls?

Any system that can make an HTTPS request: a dialer, a meeting tool, a data pipeline or a script. Each one sends under a source name that Zime registers for your company. If you use Nooks and export transcripts to Amazon S3, Zime has a sender script for those exports.

What do I need before I send the first call?

Three things. An ingest key, which a company admin generates in Zime. A source, which Zime registers and turns on for your company. And every rep on your calls set up as an active Zime user. Until Zime turns the source on, the API answers 422 unknown_source.

How do I get my source turned on?

Email support@zime.ai or ask your Zime contact. Name the system that will send your calls, and say whether it sends dialer calls or meetings.

Zime registers the source for your company, sets its rules with you and turns it on. You can generate the ingest key before or after. Until the source is on, the API answers 422 unknown_source and stores nothing.

Ingest key

11 answers
Who can generate an ingest key?

Any company admin. In Zime, go to Admin, then APIs, and press Generate key in the Ingest key (write) card. Only company admins see the APIs tab.

Where do I find the key again later?

Go to Admin, then APIs, and press Show key or Copy in the Ingest key (write) card. A shown key hides again after a minute. Zime records who showed or copied it, and when, under See history.

What does the key look like?

A 43 character string of letters, digits, hyphens and underscores. Zime shows its last four characters so you can tell keys apart.

How do I send the key?

In the X-API-Key header of every request. Header names are not case sensitive, so x-api-key works too. A key in the URL or in an Authorization: Bearer header is not read, and the request returns 401 api_key_required.

Is the ingest key the same as my API key?

No. They are separate keys on the same screen. The ingest key can send calls and check their ingest status; it cannot read calls, transcripts or insights. Your API key cannot send calls: the Call Ingest API answers it with 403 invalid_api_key.

Can we have more than one ingest key?

No. A company has one active ingest key at a time, and all of its sources use it.

How do I rotate the key?

Press Generate new key. The old key stops working the moment the new one is created, so update your scripts with the new key before you close the screen.

What happens to calls already sent when I rotate or revoke the key?

Nothing. A call Zime has accepted keeps processing. The old key only stops new requests, which get 403 invalid_api_key.

How do I revoke the key?

Press Revoke. Your company cannot send calls until an admin generates a new key. Requests with the revoked key get 403 invalid_api_key.

Can I see who generated, showed or revoked the key?

Yes. Press See history. It lists the last 50 changes with the person and the time.

What should I do if the key leaks?

Generate a new key straight away; the leaked key stops working at once. Until then, anyone holding it can send calls into Zime under any active rep in your company, and can read your ingest status list: sources, external_call_id values, call times, errors and zime_call_id. It cannot read calls, transcripts or insights. After you rotate, check GET /api/v1/calls/ingest for calls you did not send, and email support@zime.ai to have them removed.

Sending a call

16 answers
Which fields are required?

source, external_call_id, started_at, ended_at, rep with an email, at least one participant, and a transcript, a recording or both. At least one participant who is not the rep needs an email or a phone. Everything else is optional.

What are source and external_call_id?

source names the system that sent the call. Zime registers it for your company: 2 to 40 lowercase letters, digits or underscores. external_call_id is that system's own ID for the call: 1 to 128 letters, digits, dots, underscores, colons or hyphens. Together they identify the call. IDs that differ only in letter case are the same call.

Which date and time format do you accept?

ISO 8601 with a time zone, for example 2026-10-19T09:43:35Z or 2026-10-19T15:13:35+05:30. Seconds and fractions of a second are optional. A time without a zone, or a date alone, returns 400 invalid_payload. Write each call's times the same way every time you send it: the same moment with a different offset counts as changed content.

Are there limits on call dates and length?

Yes. started_at can be up to 400 days in the past and up to 1 day in the future. ended_at cannot be before started_at, or more than 24 hours after it. Zime can also set an oldest date for your source; calls before it are skipped with the reason rule:backfill_from.

Is there a limit on participants?

Yes. A call can list up to 100 participants.

What format should phone numbers use?

Zime does not check phone formats. It shows the number as you send it, for example in the title of a call whose prospect has no name. Sending E.164, such as +14155550123, keeps numbers consistent.

Which email addresses are accepted?

Plain addresses: letters, digits and . _ % + - before the @, and a domain with a dot. An address with an apostrophe or an accented letter returns 400 invalid_payload, so leave it out and send the phone instead. Zime stores emails in lowercase.

What are the participant roles?

Each participant has a role: prospect, rep or other. A participant with the rep's email counts as the rep. Transcript segments use the same three roles in speaker_role.

What is the difference between a dialer call and a meeting?

call_type is dialer or meeting, and each source has one, set by Zime when it registers the source. Leave call_type out, or send dialer or meeting: the one that is not your source's type returns 422 call_type_mismatch, and any other value returns 400 invalid_payload. Dialer calls are exempt from the short call and no show checks for meetings, never trigger the post call email, and are listed under Dialer on the Calls page.

What does a transcript look like?

An object with format set to segments and a list of segments. Each segment has speaker_role, speaker_name, start_seconds, an optional end_seconds, and text. Send 1 to 5,000 segments, ordered by start_seconds, with up to 10,000 characters of text each. WebVTT, SRT and plain text are not accepted: convert them to segments first.

What if I do not know a speaker's name or when a segment ends?

Send speaker_name as an empty string. Zime then uses the rep's name or the prospect's name from the call, or Sales Rep, Prospect or Speaker. Leave end_seconds out, and Zime estimates it from the length of the text.

Does Zime change the text I send?

Only a little. Line breaks become spaces, and the sequence --> becomes ->, in segment text, speaker names, participant names, phones and the title. Colons in speaker names become spaces.

What is the size limit for one request?

1 MB (1,048,576 bytes) of JSON, sent with Content-Type: application/json. A larger body returns 413 payload_too_large. A request with another Content-Type returns 400 invalid_payload.

Can I add my own fields?

Yes, in metadata: up to 50 keys, with string values of up to 500 characters each. Zime keeps them with the call. Fields this reference does not list are ignored. A resend that changes only metadata does not count as a change.

What happens if I leave out the title or direction?

direction defaults to outbound. Without a title, Zime names the call from its direction and prospect, for example [OUTBOUND] [CALL] with Pat Prospect, using the prospect's name, else phone, else email.

What does disposition do?

It records the outcome from your dialer, such as Meeting Set, in up to 120 characters. Your source's rules can keep or skip calls by disposition. Rules match it exactly, including letter case.

Recordings

6 answers
Can I send a recording instead of a transcript?

Yes. Put an https link to the file in recording.audio_url. Zime downloads it and transcribes it. The call's status is queued until its turn, then processing. Once the recording is stored, the reason reads Waiting for speech to text until the transcript is ready. In our tests, with short test recordings and few calls queued, this took 1 to 3 minutes. A job still pending after 4 hours counts as a failed attempt.

Which file formats and sizes are accepted?

WAV, MP3, M4A, OGG, FLAC, WebM, MP4 and MOV, up to 1.5 GB. Zime reads the format from the file itself, or else from its Content-Type. The download must finish within 30 minutes. A link that returns anything else, such as a sign in page, fails with Recording URL did not return audio or video.

What if I send both a transcript and a recording?

Zime keeps your transcript and stores the recording with the call. It does not transcribe the recording again. If the recording cannot be downloaded, the call still completes with your transcript, and recording_status shows failed with the reason. A resend cannot add the recording to a completed call.

How are speakers named when Zime transcribes a recording?

Speech to text labels speakers by voice. When it hears two or more voices, Zime uses AI to tell the rep from the prospect and names them: the rep from rep.name, else the rep's name in Zime, and the prospect from the prospect's name, else their phone. When it hears one voice, or cannot tell who is who, it keeps a generic label such as Speaker 0. If the prospect has no name and no phone, every speaker keeps a generic label. Send the prospect's name, or a transcript with speaker_name, to get named speakers.

Skipped calls

6 answers
Which calls does Zime skip?

The ones your source's rules drop. Zime sets the rules for each source with you. They can set an oldest call date; dispositions to always keep, to keep only, or to exclude; a minimum duration; a minimum number of turns on each side; a minimum number of transcript characters; and whether to drop calls with no transcript, which is on unless you ask for it off. A skipped call is answered 200 with status skipped and a reason such as rule:min_duration_seconds.

In what order are the rules checked?

The oldest call date first, and nothing bypasses it. Then dispositions to always keep, which bypass every other rule. Then no transcript; minimum turns and minimum characters, only when a transcript is sent; minimum duration; dispositions to keep only; and dispositions to exclude. The first rule that fails names the reason.

What counts as no transcript?

A call with no recording whose segments are empty or say only No transcript available. A call with a recording is not dropped by this rule, because Zime transcribes the recording.

Does Zime store anything from a skipped call?

Only its status record, such as the source, external_call_id, start time and reason. A call skipped when it arrives is never stored. A call skipped during processing has its content cleared.

How do I change the rules for my source?

Email support@zime.ai. Zime sets the rules for each source. When you resend a call that a rule skipped, Zime judges it again under the rules in force at that time.

How do I find out why a call was skipped?

The response tells you: status skipped and a reason. You can read it again later from the status routes. Reasons that start with rule: come from your source's rules. Other reasons come from processing, for example No integrated attendee when the rep stopped being an active Zime user after the call was accepted.

Duplicates, resends and updates

7 answers
What happens if I send the same call twice?

Zime keeps one copy and answers 200 with duplicate: true. A call is the same when its source and external_call_id match, so a resend never creates a second copy.

Do you support an idempotency key?

Yes. external_call_id is the idempotency key. There is no separate header.

Can I update a call I already sent?

Only while it is queued. A resend with changed content replaces the queued copy and returns 200 with updated: true. Once processing has started, changes are ignored and the answer is 200 with duplicate: true and content_changed: true.

What counts as changed content?

A change to any field except metadata. The same moment written with a different time zone offset also counts as a change.

How do I retry a failed call?

Send it again with the same source and external_call_id. A failed call goes back to queued, and the answer is 202. Zime keeps a failed call's content, so a resend of the same content works.

Can I resend a call that was skipped?

Yes. A call a rule skipped is judged again under your source's current rules: kept now, it is queued with 202; dropped again, you get 200 skipped. A call skipped during processing, such as No integrated attendee, is final, and a resend answers duplicate.

Can I delete or replace a completed call?

Not through the API: a resend of a completed call is ignored. To delete a call, a company admin can email support@zime.ai. The privacy policy explains how deletion works.

Status, errors and limits

11 answers
What does 202 mean?

Zime has accepted the call and queued it. It has not processed it yet. Check its status to see when it completes.

How long until a call is processed?

Zime's worker picks up queued calls in turn, at most 5 every 30 seconds. Measured in production in November 2026, with few calls queued: a call with a transcript reached completed about 10 to 45 seconds after it was sent, and its summary and insights were ready about 4 to 7 minutes after it was sent. A recording-only call reached completed 1 to 3 minutes after it was sent on short test recordings, and its summary and insights follow after that. These are measured times, not a guarantee: waits grow when many calls are queued, so follow a backfill with the list route.

How do I check one call?

Send GET /api/v1/calls/ingest/{source}/{external_call_id} with your ingest key. It returns the status, the reason or error, and zime_call_id once the call is in Zime. A call Zime has no record of returns 404 not_found.

How do I check many calls?

Send GET /api/v1/calls/ingest with the filters source, status, start-date and end-date. Calls come oldest first, 100 a page by default and up to 1,000 with page-size. While has_more is true, pass next_cursor as after-key.

Which dates do the list filters use?

The call's started_at. Use YYYY-MM-DD, read as UTC with the end date included, or an ISO 8601 time with a zone. An impossible date such as 2026-02-30 returns 400 invalid_payload.

What do the statuses mean?

queued: accepted and waiting. processing: being processed, or waiting for speech to text. completed: the call is in Zime. skipped: not added; see reason. failed: could not be added; see error, fix the cause and resend.

How many times does Zime retry a call that fails?

Up to 3 attempts for errors that can pass, such as a recording server that is briefly down on a call sent without a transcript. A permanent error, such as a recording link that returns 404, is not tried again. Either way the call ends as failed with an error, and you can resend it. On a call sent with a transcript, a failed recording download does not hold the call back: the call completes with recording_status failed.

What is zime_call_id?

The ID of the call in Zime. It is the same ID the REST API returns as call_id, so you can join ingest status to calls, insights and transcripts.

Should I retry errors?

Retry 429 after the number of seconds in Retry-After, and 500 or 503 with growing waits. Do not resend 400, 401, 403, 413 or 422 unchanged: fix the cause first. A resend never creates a second copy of a call.

What is the rate limit?

About 600 requests a minute for each key on each Zime server instance. Zime runs more than one instance and the number changes, so plan for 600 a minute per key. Above that Zime may answer 429 rate_limited with a Retry-After header, in seconds.

How many calls can Zime process at once?

The API accepts calls up to the rate limit, up to 1 MB each, and queues them. Zime's worker then takes up to 5 queued calls every 30 seconds, in turn across sources, and in production today one worker does this for all companies. A large backfill is accepted at once and processed over time.

What you see in Zime

9 answers
Where do the calls appear in Zime?

On the Calls page, in the Recordings tab, as calls of the rep in rep.email. Dialer calls are hidden by default: tick Dialer in the call filters to see them.

How soon does a call show in Zime?

Zime creates the call while it processes it, so the call is in Zime once its status is completed, with its zime_call_id. In our production tests, with few calls queued, that was about 10 to 45 seconds after sending for a call with a transcript, with its summary and insights ready about 4 to 7 minutes after sending. On short test recordings it was 1 to 3 minutes for a recording-only call, with its summary and insights following after that. The worker picks up queued calls in turn, so these are measured times, not a guarantee.

How is the rep matched?

By rep.email, to an active Zime user in your company. Letter case does not matter. With no such user the API returns 422 rep_not_found. With a user who is not active, for example deactivated or still pending approval, it returns 422 rep_inactive: activate or approve the user, then resend.

What if a rep is not in Zime yet?

Add them as a Zime user, and make sure the user is active, not pending approval. Then send the call again. A call refused with 422 is not stored, so the resend is accepted as a new call.

Can a prospect have only a phone number?

Yes. At least one participant who is not the rep needs an email or a phone, and a phone alone is enough. A prospect with only a phone makes the call external.

When is a call treated as internal?

When every participant who is not the rep has an email on your company's own domain. Zime builds no insights for an internal call. A prospect sent with the rep's email counts as the rep, so that call is internal too.

How is the call linked to a CRM deal?

Zime maps it to a deal itself, usually within 2 minutes of creating the call in our production tests, and checks again later while no deal is linked. Not every call matches a deal. You do not send deal IDs. The deal can be changed from the call page in Zime, as for any call.

Will a pushed call get checklists, a summary and insights?

Yes. Zime matches each pushed call to your company's checklists the same way as other calls, including checklists set up for its source, and queues them for processing. It builds the summary and insights like any other call, unless the call is too short, internal or a no show. A call whose stored transcript, timestamps and speaker names included, is under 500 characters for a dialer call or 800 for a meeting gets no insights. A meeting under 5 minutes, or one where only the rep spoke, is treated as short or a no show; dialer calls are exempt from both checks.

Does a pushed call send the post call email?

Not for dialer calls: they never trigger the post call email. A pushed meeting goes through the post call email step the same way as any other meeting.

Data and security

5 answers
Is the data encrypted?

Yes. Send every request over HTTPS. Once a call is in Zime it is stored like every other call, encrypted in transit and at rest, as the privacy policy describes.

What does Zime keep from a request?

For an accepted call, its content until processing ends. A completed call then lives in Zime like any other call, and the intake copy is cleared. A failed call keeps its content so you can resend it. A skipped call keeps only its status record, never its content.

Where is the data stored?

Zime stores the transcripts of pushed calls in Amazon S3 in the US East (N. Virginia) region, and their recordings in Google Cloud Storage in the US multi-region. The privacy policy covers international transfers.

How long does Zime keep pushed calls?

The same as every other call: as set by your company's agreement with Zime, otherwise until an authorized admin of your company asks us to delete them. The privacy policy has the details.

Nooks exports in Amazon S3

18 answers
If we use Nooks and export transcripts to Amazon S3, how do we send those calls to Zime?

With Zime's sender script, a Python script that reads the call exports Nooks writes to your S3 bucket and sends each call to the Call Ingest API. It runs in your own AWS account, so your bucket access stays with you. Zime shares the sender script and the setup steps over a secure channel. Your company admin generates the ingest key in Zime under Admin, then APIs; keep it in your secret store and never send it by email or chat in plain text.

What does the script need?

Python 3 with boto3, which the AWS Lambda Python runtime already includes. Your ingest key in ZIME_INGEST_KEY, kept in your secret store and given to the script as an environment variable. Read access to the export bucket.

Which AWS permissions does it need?

For the Lambda role or the credentials the shell uses: s3:ListBucket on the export bucket and s3:GetObject on its objects, always. With the watermark in the export bucket, add s3:PutObject on the watermark key; the two above already cover the rest. With the watermark in a separate bucket, add s3:ListBucket on that bucket, and s3:GetObject and s3:PutObject on the watermark key. s3:ListBucket on the watermark's bucket is required: without it, S3 answers a read of a watermark that does not exist yet with AccessDenied instead of NoSuchKey, the script treats only a missing object as a first run, and every scheduled run would fail before sending anything. A watermark in a local file needs no S3 permission.

How do we give the script the key when running it from a shell?

The script reads the key only from the environment. Never type the key into a command, because it would then be saved in the shell history. Load it in one of these ways; the commands in these answers then run without the key. 1. Export it from your secret store. 2. In bash (run it in bash, e.g. start bash first), run read -rs ZIME_INGEST_KEY && export ZIME_INGEST_KEY then paste the key at the hidden prompt and press Enter. 3. In any POSIX shell, such as sh or dash, run stty -echo; printf 'Ingest key: '; IFS= read -r ZIME_INGEST_KEY; stty echo; printf '\n'; export ZIME_INGEST_KEY then paste the key at the Ingest key prompt and press Enter. The key is not shown on screen and is not saved in the history. If you press Ctrl-C at the prompt, your typing stays hidden; type stty echo and press Enter to see it again.

What S3 layout does it expect?

The layout Nooks writes: one folder per day, named YYYY_MM_DD after the call's UTC start date, holding one Nooks-*.zip per call with a metadata JSON file and a transcript text file.

What does it send for each call?

The Nooks callId as external_call_id, the start and end times, the direction, the disposition, the first participant as the rep, the last participant as the prospect, and the transcript. Nooks exports have no audio, so no recording is sent.

How should we run it?

Always run the scheduled mode: the same Lambda handler on an EventBridge schedule, every 15 minutes or once a day after 09:30 UTC. It keeps a watermark, its place in the bucket. When the key is refused, the source is not on yet, or errors outlast the retries, the run stops and keeps its place, so the next run tries that call again. A call Zime refuses for itself, such as rep_not_found, is logged and passed over; see the next answers. You can add an S3 ObjectCreated trigger beside the schedule for faster delivery; both send the same calls and Zime answers duplicate to the repeats. Do not run S3 events alone: a call an event cannot send is dropped after Lambda's retries. Set the Lambda timeout to 900 seconds and the memory to 512 MB; the 3 second default timeout is too short.

What does the script do with each answer from Zime?

Accepted (queued, skipped by your rules, duplicate or updated): counted, and the run moves on. Refused for that call (a 400, or a 422 such as rep_not_found or rep_inactive), or an export it cannot read: logged and counted as rejected:<error> or bad_export, and the run moves on; in a scheduled run its watermark moves past the call, so no run sends it again by itself. 401, 403, 422 unknown_source, and 429, 5xx, network or S3 read errors that outlast the retries: the run stops; a scheduled run keeps its watermark and the next run starts with that call, while an S3 event is dropped after Lambda's retries.

How do we resend calls Zime refused?

Fix the cause first, for example add the rep in Zime and make sure the user is active. Zime stores nothing for a refused call, so the resend is accepted as a new call. Then, with the key loaded as in the answer on running from a shell, run NOOKS_BUCKET=<bucket> python3 nooks_ingest.py --key <object key> for one call, or resend its window. To resend a window, load the key as in the answer on running from a shell, then run the scheduled mode once with START_DATE set to the day before the problem began and a watermark file that does not exist yet, using NOOKS_BUCKET=<bucket> START_DATE=<YYYY-MM-DD> WATERMARK_URI=nooks_resend_watermark.json python3 nooks_ingest.py as the command. Use a new watermark file, never the one of your scheduled run: a run with an existing watermark starts from that watermark, not from START_DATE. If the run stops early, run the same command again and it continues from its own watermark. It sends every call in the window, and the ones Zime already has answer duplicate; add --dry-run first to see the count as would_send.

Will Nooks's double export create duplicates?

No. Nooks writes each call twice: soon after the call, and again in a 09:00 UTC batch the next day. The second copy answers duplicate.

How do we backfill older calls?

Set START_DATE to the oldest day to send, as YYYY-MM-DD; the default is 2026-08-06. The first scheduled run sends everything from that date and continues on the next run if it runs out of time. Zime still skips anything older than your source's oldest call date.

How do we test it safely?

Run python3 nooks_ingest.py --dry-run first. It reads the bucket, sends nothing, moves no watermark and reports would_send. Then send one call with --key and the object key, and check it with the status route.

Which calls does the script not send?

Exports whose transcript says only No transcript available, calls with one participant, and day folders before START_DATE. Each run counts them. A prospect email of No email found, or one with characters Zime does not accept, is left out and the call is still sent.

What does the script log?

Counts of each outcome per run, and one line per call with the call ID only: never a transcript, an email, a phone or the key.

What if a run gets 401 or 403?

The key was refused, so the script stops sending. A scheduled run saves its watermark on the last call done and stops; on Lambda the invocation ends in an error, and from the command line it exits with status 1. The next run starts with the call that failed and sends nothing before it again. An S3 event run fails the event; Lambda retries it, twice by default, and then drops it; the scheduled run sends that call, which is why it must always run. Fix the key: check that ZIME_INGEST_KEY holds the current key, because a new key or a revoke stops the old one. 403 company_inactive means your company is not active in Zime; email support@zime.ai. Then let the scheduled run continue. Only S3 events running without the scheduled mode miss calls. To resend a window, load the key as in the answer on running from a shell, then run the scheduled mode once with START_DATE set to the day before the problem began and a watermark file that does not exist yet, using NOOKS_BUCKET=<bucket> START_DATE=<YYYY-MM-DD> WATERMARK_URI=nooks_resend_watermark.json python3 nooks_ingest.py as the command. Use a new watermark file, never the one of your scheduled run: a run with an existing watermark starts from that watermark, not from START_DATE. If the run stops early, run the same command again and it continues from its own watermark. It sends every call in the window, and the ones Zime already has answer duplicate; add --dry-run first to see the count as would_send.

What if a run gets 422 unknown_source?

Zime has not turned your source on yet. A scheduled run stops without moving its watermark, and the first run after Zime turns the source on sends everything from that call. An S3 event that gets this answer fails and is dropped after Lambda's retries; the scheduled run sends that call.

How does it handle 429 and server errors?

It tries 429, 5xx and network errors up to 6 times in all, with growing waits, and honours Retry-After up to 30 seconds. If they persist, the run stops the same way as for a refused key: a scheduled run keeps its watermark and the next run starts from the call that failed, while an S3 event is dropped after Lambda's retries. That is why the scheduled mode should always run.

How do we resend one call?

Fix the cause, then, with the key loaded as in the answer on running from a shell, run NOOKS_BUCKET=<bucket> python3 nooks_ingest.py --key <object key> for that call. If Zime already has the call, it answers duplicate.

Support

1 answer
Who do I contact for help?

Email support@zime.ai with your company name, the source, the external_call_id and the response you got. Never send the key.

Still need help?

Write to support@zime.ai and the team will get back to you.

Email support
Call Ingest API · Zime help