Best for
- welcoming a customer who just signed up and confirming they can get started
- collecting first-party onboarding context: business type, goal, prior tooling, blockers
- detecting whether a customer wants a human to follow up
CALLE-AI/awesome-phone-call-agents/skills/customer-onboarding-call/SKILL.md
Place a one-off welcome and onboarding call to a customer who just signed up, capture a structured result such as business type, goal, pain points, sentiment, and activation status, then write that result back to a CRM and queue a human follow-up task when the customer asks for one.
Decision brief
Use this skill when a new signup should receive a short welcome call and the business wants the conversation to end as structured data rather than as an unread recording.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/CALLE-AI/awesome-phone-call-agents --skill "skills/customer-onboarding-call"Inspect the Agent Skill "customer-onboarding-call" from https://github.com/CALLE-AI/awesome-phone-call-agents/blob/a34d6b803ee2f1b80446056dcef38911882726e5/skills/customer-onboarding-call/SKILL.md at commit a34d6b803ee2f1b80446056dcef38911882726e5. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
1. Confirm the signup is real and recent, and that this customer has not already been called. 2. Build the call task from the required fields. Keep the script to roughly two minutes. 3. Attach a structured result schema so the provider returns fields, not just a transcript. See…
Reachability is decided on call evidence, never on whether a structured result exists. A real conversation can return no result at all: extraction failed, the result failed validation, or the customer refused and rang off before the model emitted anything. Inferring "nobody answ…
Review the “Stage B — a human took part, so consent governs” section in the pinned source before continuing.
welcoming a customer who just signed up and confirming they can get started
Do not use this skill to:
Permission review
No configured static risk pattern was detected
This is not proof of safety. Runtime behavior, indirect dependencies, and hidden external systems are outside the static scan.
Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 98/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 66 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Use this skill when a new signup should receive a short welcome call and the business wants the conversation to end as structured data rather than as an unread recording.
customer-onboarding-call turns one signup event into at most one conversation, one structured
result, and at most one follow-up task. Obtaining that conversation may take up to three attempts on
an unreliable corridor, with only one attempt in flight at a time; see Attempts, Retries, and
Cancellation. It does not create recurring schedules, call campaigns, or contact lists. Recurrence,
if the business wants it, belongs to the host scheduler; see call-reminder.
The workflow is deliberately narrow: welcome, consent, discovery, next-step offer, wrap-up. A call that tries to sell, negotiate, collect payment, or resolve a support ticket is out of scope.
Use this skill for:
Do not use this skill to:
For each call, require:
customerNamephoneNumber in E.164companyName for the agent to introduce itself ascompanyDescription, one sentence the agent may state as factOptional:
businessNamelocale and region hints for the conversationAsk for any missing required field. Do not infer a phone number, country code, or region from a locale, an IP address, an email domain, or unrelated prior context.
references/structured-result.md.(signup_id, attempt_no) before
dialing, and derive the provider idempotency key from it. Refuse to start a new attempt while
another is in flight for the same signup.onboarded and the customer asked for one.Use this shape:
signup -> attempt record -> call task + result schema -> attempt -> terminal webhook
-> classify -> permitted CRM write -> follow-up or retry or suppress
Keep the call in this order. Allow interruption at any point.
The agent may answer only from companyDescription and any knowledge base you explicitly supply.
For anything else — price, delivery time, policy, availability — it must say it will have a human
follow up. Inventing these is the most common failure mode of onboarding-call agents.
The full contract in one view. Every arrow that ends in a call is guarded; every terminal state says what it permits.
signup
|
v
[ allocate attempt no > cap? ]---- yes -->( manual handling )
| ^
no |
v |
[ attempt live (leased) ] |
| |
+-------------------+--------------------+ |
| | | |
terminal result lease expires create failed |
| | | |
| v | |
| [ reconcile with provider ] | |
| | | | | |
| terminal still live unknown | |
| | | | | |
+<------------+ v | | |
| ( ambiguous )-+-------+ |
| | (late result re-enters) |
v | |
== STAGE A: was a human reached? == |
reachability from CALL EVIDENCE, not from "is there a result" |
| |
+-- refusal evidence present? --> ( declined ) |
| |
no-human — CLOSED evidence set only: voicemail / carrier msg /
ring-out / no-answer / silence / provider machine signal |
+--> ( not-reached ) ------------------ retry allowed ---+
| |
+--> ( failed ) provider positively says NO CALL PLACED --+
|
+--> ( needs-review ) indeterminate: provider unreachable,
| unknown attempt, expired lease, extractor-only NotReached,
| billing charge with no obtainable outcome. NO RETRY.
|
human
v
== STAGE B: consent governs ==
|
+--> ( declined ) terminal. suppress per scope. no follow-up, no retry, ever.
+--> ( needs-review ) no result at all, unusable consent fields, or indeterminate
| reachability. terminal until a human decides. NO auto retry.
+--> ( partial ) write captured fields only. retry ONLY with callback consent
| or human authorisation, and only under the cap.
+--> ( onboarded ) write insight. follow-up only if requested.
Invariants the diagram encodes:
NotReached, an unreachable provider, an expired lease, and a billing charge
are all unknown — they route to needs-review, never to a retry.declined from anywhere, with or without a result.declined.needs-review, which never retries.ambiguous is provisional —
a late result re-enters classification from the top.A call that reaches a terminal state has not necessarily reached a consenting human. Providers commonly return a completed call with an empty structured result when the agent talked to a carrier message, voicemail, or silence. A call can also produce a perfectly well-formed structured result while the customer was refusing to take part.
The presence of a structured result is not evidence of consent. Classification is therefore
driven by an evidence-backed disposition field, not by whether a result exists. See
references/structured-result.md.
Classify in two stages, in this order. Stage A decides whether a human took part at all. Only if one did does Stage B read consent.
The staging is the contract, not a presentation choice. Consent fields are meaningless when nobody
answered — a voicemail grants no consent, so consent_granted is false there. Reading consent
before establishing that a human was reached turns every no-answer into a refusal.
Reachability is decided on call evidence, never on whether a structured result exists. A real conversation can return no result at all: extraction failed, the result failed validation, or the customer refused and rang off before the model emitted anything. Inferring "nobody answered" from a missing result would auto-retry those calls and redial a person who may have just refused.
Exactly one thing authorises an automatic redial: observed evidence from the call itself that no person took part. This is a closed list.
| Counts as no-human evidence | |
|---|---|
| voicemail or answering-machine greeting | carrier or network announcement |
| ring-out with no answer | the provider's own answered-by-machine / no-answer signal |
| silence throughout after the agent spoke |
Nothing else qualifies. In particular these are not no-human evidence, however tempting:
disposition: NotReached — that is a model claim about the call, not an
observation of it, and the same extractor mislabels refusalsEvery one of those means we do not know. Unknown is needs-review, never a retry. The
asymmetry is deliberate: a needless manual check costs a minute, and a wrong redial reaches someone
who may have already refused.
| Reachability | Evidence |
|---|---|
human | the provider reports a human answered, or the transcript contains customer speech that is not carrier or IVR audio |
no-human | at least one item from the no-human evidence set above, and no contradicting customer speech |
indeterminate | anything else, including every "not evidence" item listed above |
| # | Outcome | Condition | Action |
|---|---|---|---|
| A1 | not-reached | reachability is no-human | write no insight; queue a retry; never suppress the number |
| A2 | ambiguous | provider reported failure and reconciliation has not completed | write nothing; schedule reconciliation, not a retry |
| A3 | failed | provider reported failure and reconciliation positively establishes that no call was placed | write no insight; queue a retry; never suppress the number |
| A4 | needs-review | reachability is indeterminate — provider unreachable, unknown attempt, expired lease, extractor-only NotReached | write nothing beyond the raw record; no automatic retry; route to a human |
disposition: NotReached may corroborate no-human evidence, and it may never substitute for it.
On its own it yields needs-review, not not-reached.
Note the strictness of A3: reconciliation must show the call did not happen. "The provider does not know" is not that; it is A4. Only a definite negative — no such call, never dialled — releases a retry.
Where reachability is human, continue to Stage B; a missing or unusable result there resolves to
needs-review (B2), which never retries automatically.
Refusal evidence outranks everything in this stage. If the transcript or provider summary shows
the customer refusing or asking not to be called — even with no structured result, and even where
the provider labelled the call NotReached — classify as declined (B1) and apply the suppression
scope. A refusal that lost its structured result is still a refusal.
Stage A never suppresses a number and never records a refusal of its own accord. A customer who did not answer has not refused anything.
| # | Outcome | Condition | Action |
|---|---|---|---|
| B1 | declined | disposition is Declined or DoNotCall, or consent_granted is false | record the refusal and its evidence; write no onboarding insight; queue no follow-up; cancel any pending retry; apply the suppression scope below |
| B2 | needs-review | no structured result at all, or required consent or disposition fields are missing, malformed, or contradicting the transcript, or reachability was indeterminate | write nothing beyond the raw record; no automatic retry; route to a human |
| B3 | partial | disposition is EndedEarly | write only the fields actually captured and mark the record partial; queue no follow-up unless the customer explicitly asked and evidence supports it; retry only under the callback-consent rule below |
| B4 | onboarded | disposition is Completed and consent_granted is true and a structured result is present | write insight; queue a follow-up only when requested |
Declined and DoNotCall both end this signup, but they are not the same instruction and must not
be recorded identically.
| Disposition | The customer said | Scope |
|---|---|---|
Declined | not now, not this call | Suppress this onboarding workflow for this signup. Other contact the customer has separately opted into — transactional notices, support replies, a channel they initiated — is unaffected. |
DoNotCall | stop calling me | Suppress all outbound calling to that number, across every workflow, indefinitely. Propagate it to the shared do-not-call record, not just this signup's row. |
If you cannot tell which the customer meant, record DoNotCall. Over-suppressing costs a
conversation; under-suppressing means calling someone who told you to stop.
Neither may be lifted by a later call result. Only an explicit opt-in from the customer through another channel can reverse a suppression, and that reversal belongs to whatever system owns consent — not to this skill.
Rules that follow from the staging and must not be relaxed:
not-reached,
ambiguous, and failed must never mark a number do-not-call.onboarded, or from partial with explicit evidence
of a request. Never from declined, needs-review, not-reached, ambiguous, or failed.onboarded. declined and partial may write only their disposition and evidence.needs-review, never not-reached.
Coercing it to not-reached would queue an automatic retry and could redial someone who actually
refused. When you cannot tell whether a human took part, treat the call as reached and route to
review — the failure mode of a needless manual check is trivial; the failure mode of redialling a
refusal is not.Never present not-reached as a success. A dropped signup that displays as onboarded is worse than
a visible failure, because nobody follows up.
International termination is unreliable in some corridors, and the same configuration can succeed
and then fail minutes later. See
references/international-routing.md.
One signup yields at most one conversation, and at most one attempt in flight at any moment. It may take up to three attempts to obtain that one conversation.
"One call per signup" would be the wrong guarantee — it cannot survive a corridor that drops half its calls. The guarantee that matters is that a customer is never called while another attempt for the same signup is live, and never called again once a conversation has happened.
A conversation is any call a human took part in — Stage B — including partial. Retries exist
to obtain a conversation, never to resume one. Once Stage B is reached, the attempt budget is spent
and further automatic calling stops. The single exception is an explicit, evidence-backed callback
request; see Redialling after a conversation below.
Retries are only safe if each attempt is durably recorded before the call is placed.
Allocate the next attempt_no for the signup and persist an attempt record under a uniqueness
constraint on (signup_id, attempt_no). If the insert conflicts, another worker owns this
attempt — stop.
Enforce at most one live attempt per signup with its own constraint — a partial uniqueness
constraint on signup_id restricted to non-terminal states. Uniqueness on
(signup_id, attempt_no) alone does not provide this: two workers can allocate attempt 2 and
attempt 3 concurrently and both dial.
Bind the idempotency key to the canonical call payload, not just to the attempt slot. Derive it deterministically from the attempt identity and a digest of exactly what will be dialled:
attempt_key = onboarding:<signup_id>:<attempt_no>:<digest>
digest = hash( E.164 destination + task/script version + result-schema version + locale )
onboarding:<signup_id>:<attempt_no> alone identifies a slot, not a call. If the destination
number is corrected, the script revised, or the schema changed between attempts, that key would
silently cover a materially different call — and reconciliation would match a provider record
that is not the one you placed, which is how a "no record found" turns into a wrong redial.
Include the destination in the digest so a changed number can never inherit a prior attempt's
identity.
Never derive an idempotency key from a timestamp, a random value, or a retry counter held only in memory. A key that changes on redelivery is not an idempotency key.
Reconcile on the key, and verify the payload matches before believing the answer. A provider
record whose destination or script digest differs from the attempt you are reconciling is not
evidence about that attempt — treat the attempt as needs-review.
Key webhook ingestion on the provider event id so redelivery cannot advance state twice.
If placing the call fails after the attempt record exists — provider rejection, timeout, crash — close that attempt out before returning. An attempt left live because the call was never actually placed blocks the signup forever.
Blocking new attempts while one is live is only safe if a live attempt cannot last forever. A terminal webhook can be lost to a deploy, a signature change, or a provider outage. Without an expiry the signup is stranded permanently: never resolved, never retried, and invisible because nothing failed.
ambiguous.failed.
This is the only lease-expiry path that releases a retry, and it requires a definite negative.needs-review. Release the signup so it is no longer blocked, but do not queue a retry.ambiguous, needs-review, or a reconciled terminal result — never not-reached, never
declined, never onboarded, and never a retry on its own.A provider failure report is not proof that no call was placed. A degraded control plane can report failure and dial minutes later.
ambiguous rather than failed, and schedule a
reconciliation check instead of a retry.needs-review — a human reads the record. It is never not-reached, because a
placed call may have reached someone who refused.ambiguous to failed, and only then schedule a retry, when reconciliation
positively establishes that no call was placed. "The provider has no record" is not that;
absence in a log you cannot fully trust is needs-review.ambiguous is provisional, not a verdict. If a late result arrives — from the delayed webhook
or from reconciliation — re-run the full classification on it, Stage A then Stage B. A call that
looked failed can turn out to have been a real conversation, including a refusal, and that refusal
must take effect exactly as if it had arrived on time. Never let a provisional ambiguous or a
scheduled retry outrank a real outcome that shows up late; cancel the retry instead.
Automatic retries are permitted only for Stage A outcomes, where no human took part and so no conversation has happened:
not-reached and reconciled failed.declined, partial, or needs-review.timezone field, or derive
it from the region supplied with the signup. Do not guess from the phone number's country code
when that country spans several zones, and do not fall back to the operator's own clock. If the
timezone cannot be established, do not schedule an automatic retry — surface it for manual
scheduling instead. An unknown timezone is a reason to ask, not a reason to dial.A partial call is a conversation that ended early. The customer may have hung up because they
did not want to continue, and the workflow cannot tell the difference from a dropped line. So a
partial does not license another call.
Redialling after any Stage B outcome requires one of:
callback_consent with supporting words in callback_consent_evidence. Honour a stated time
or window. Absent or generic evidence does not qualify — silence, politeness, and an
unfinished answer are not a callback request.needs-review always takes route 2. A malformed or contradictory consent record must never be
resolved by calling the customer again to find out.
A redial authorised this way is a new attempt against the same cap. It never resets the budget, and
declined remains terminal regardless of any later callback claim.
Every scheduled retry must be cancellable, and must carry a stable id so it can be addressed.
Cancel automatically when any of these occur:
declined, or the customer requests do-not-call by any channelCancellation must be idempotent, must be safe to call for an already-cancelled or already-fired retry, and must record what triggered it. If the host cannot cancel a scheduled job, do not schedule one — surface the retry as a manual task instead, and say so rather than implying a retry is pending.
Read references/safety.md for the full contract. Always:
After an attempt, report:
onboarded, partial, declined, needs-review, not-reached, failed, or
ambiguous while reconciliation is pendingdisposition and the disposition_evidence that supports itIf no call was placed, report status: not called, the exact blocker, and what the user must
supply next.
Never claim a customer was onboarded, interested, or requesting contact without a Completed
disposition and granted consent to support it. A populated structured result alone is not
sufficient — a refusal can carry one.
Frequently asked questions
Use this skill when a new signup should receive a short welcome call and the business wants the conversation to end as structured data rather than as an unread recording.
The source record exposes this install command: npx skills add https://github.com/CALLE-AI/awesome-phone-call-agents --skill "skills/customer-onboarding-call". Inspect the command and pinned source before running it.
Alternatives
K-Dense-AI/scientific-agent-skills
Medicinal chemistry filters for compound triage. Apply drug-likeness rules (Lipinski, Veber, CNS), structural alert catalogs (PAINS, NIBR, ChEMBL), complexity metrics, and the medchem query language for library filtering.
davepoon/buildwithclaude
Automate Zoho CRM tasks via Rube MCP (Composio): create/update records, search contacts, manage leads, and convert leads. Always search tools first for current schemas.
JasonColapietro/suede-creator-skills
Suede-owned Instagram growth operating system for account-specific audits, Reels, carousels, Stories, conversion mapping, calendars, and daily candidate-production loops. Use when the user names Instagram, IG, Reels, Stories, asks to analyze recent posts, grow a handle, run a daily workflow, create or repurpose Instagram content, or distinguish views from follows, leads, and sales. NOT FOR: multi-platform organic strategy (use suede-social), full video rendering or editing (use suede-video), pai
eugenelim/agent-ready-repo
Use to drive the deployed end-to-end validation outer loop — deploy the integrated whole to an ephemeral environment, run e2e, observe telemetry, feed deployed findings back to work-loop's inner loop, redeploy, and iterate until the deployed whole converges, then stop at the human consent gate for the prod ship. Run by the release-lead agent (a peer of work-loop's supervisor, not a work-loop mode). Triggers on "run the release loop", "deploy the integrated whole and iterate", "ship it to an ephe