> ## Documentation Index
> Fetch the complete documentation index at: https://deepline.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Use LeadMagic in Deepline

> Use LeadMagic as a cost-conscious contact-resolution and verification layer. Validate before escalating to premium profile, phone, and job intent endpoints.

[Human guide: work with your agent →](https://deepline.com/docs/human/providers/leadmagic/guide.md)
Inspect one LeadMagic action before starting provider-backed work. Your first result is a verified input and output contract.

## Provider-specific requirements

Use LeadMagic as a contact-resolution, verification, and intent layer.

* Start with cheaper gates: `leadmagic_email_validation`, `leadmagic_company_search`, and `leadmagic_jobs_finder`.
* Escalate to premium contact discovery only after the target is worth it: `leadmagic_email_finder`, `leadmagic_mobile_finder`, `leadmagic_profile_search`, `leadmagic_b2b_social_email`, and `leadmagic_email_to_profile`.
* For role-based discovery, use `leadmagic_role_finder` for a single decision-maker and `leadmagic_employee_finder` when you need a wider company roster.
* `leadmagic_email_validation` is the final outbound validity gate for this layer. Default acceptance rule is `email_status == valid`. treat `catch_all` and `unknown` as unresolved unless the user explicitly accepts risk.
* LeadMagic treats catch-all domains conservatively. `email_status: "invalid"` with populated `mx_record` and `mx_provider` can mean the mailbox is unproven. It does not establish non-delivery. Before discarding the row, consider `deepline_native` validation or another validator such as `zerobounce` or `bettercontact`.
* Ads intelligence (`leadmagic_meta_ads_search`, `leadmagic_google_ads_search`, `leadmagic_b2b_ads_search`) is a **fallback**, not the default: route Meta, Google, LinkedIn and TikTok ad lookups through the Adyntel tools first (`adyntel_facebook`, `adyntel_google`, `adyntel_linkedin`, `adyntel_tiktok_search`) and only fall back here when Adyntel returns nothing. The LeadMagic ad-library endpoint has returned `UPSTREAM_ERROR` on every call since 2026-10-16. no credits are charged on those failures, but the row stays empty.
* If LeadMagic profile or phone quality is noisy on pilot rows, switch to quality-first enrichment (`crustdata_v3_person_enrich`, `peopledatalabs_enrich_contact`) before scaling. Confirm the current schema with `deepline describe <tool-id>`: CrustData V3 takes exactly one identifier family, `professional_network_profile_urls` or `business_emails`, as an array. Request the needed `fields` explicitly (for example, `contact` for contact data). do not copy the older camelCase person-enrichment payload into V3.

Operational pattern:

1. For larger or uncertain authorized work, test identity + email candidates on a representative row before scaling. A small supplied Play needs no extra pilot or repeated approval.
2. Validate with `leadmagic_email_validation` on every candidate.
3. Keep fallback order explicit in Play control flow: verify `email_1` first, then `email_2` only if the first candidate is absent or does not pass the validity gate. Tool completion alone is not a valid-email verdict.
4. Scale larger work after checking quality and assumptions. Provider changes or paid fallback calls must fit the existing authorization. inspecting a completed run does not authorize paid repair.

Use a supplied Play when it fits. When selecting one, start with
`deepline plays search "email verification"` and
`deepline describe <play-ref>`. Confirm the tool's current contract
with `deepline describe leadmagic_email_validation`.

For a custom workflow, save this as `email-verify.play.ts`. The order and payload
stay the same, but the success gate is explicit and each attempted verdict remains
available for inspection. Catch-all/unknown are unresolved, not permission to send.

```ts theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
import { definePlay } from 'deepline';

export default definePlay(
  'email-verify',
  async (ctx, input: { csv: string }) => {
    const contacts = await ctx.csv(input.csv, {
      required: ['email_1', 'email_2'],
    });
    const rows = await ctx
      .dataset('contacts', contacts)
      .withColumn('email_verification', async (row, rowCtx) => {
        const attempts = [];
        for (const [id, email] of [
          ['verify_primary', row.email_1],
          ['verify_secondary', row.email_2],
        ] as const) {
          if (!email) continue;
          const result = await rowCtx.tools.execute({
            id,
            tool: 'leadmagic_email_validation',
            input: { email },
            description: 'Verify this candidate email before accepting it.',
          });
          if (!['completed', 'no_result'].includes(result.status)) {
            throw new Error(
              `Email verification did not complete: ${result.status}`,
            );
          }
          const verdict = result.extractedValues.email_status?.get();
          const emailStatus = verdict?.status ?? null;
          attempts.push({
            email,
            emailStatus,
            verdict,
            response: result.toolResponse,
          });
          if (emailStatus === 'valid') return { email, attempts };
        }
        return { email: null, attempts };
      })
      .run({});
    return { rows };
  },
  { description: 'Verify primary and fallback emails for supplied contacts.' },
);
```

```bash theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
deepline plays check email-verify.play.ts
deepline plays run --file email-verify.play.ts --csv contacts.csv --watch
```

Validation, authentication, billing, and unexpected execution failures remain
errors. do not turn them into candidate misses. Keep the original row and evidence,
including MX fields needed for the catch-all caveat above. Retrieve existing output
with `deepline runs get <run-id>` and its full-result/export commands (for
example, save to `contacts.csv.out.csv`), rather than rerunning to inspect it.

Related docs:

* [leadmagic\_email\_validation reference](https://code.deepline.com/tools/leadmagic_email_validation)
* [leadmagic\_email\_finder reference](https://code.deepline.com/tools/leadmagic_email_finder)

## Find an applicable action

Confirm your effective workspace, then search the live catalog:

```bash theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
deepline auth status --json
deepline search "LeadMagic" --type tools --json
```

Search returns candidates. Check the returned provider and operation rather than selecting a similar title automatically.

## Inspect the selected contract

Replace `<returned-tool-id>` with the identifier returned by discovery:

```bash theme={"languages":{"custom":["/languages/deepline-prompt.json"]}}
deepline describe <returned-tool-id> --json
```

These commands do not execute the selected provider action. Read its required inputs, supported access mode, pricing unit, outputs, and limits.

A connection does not establish that every action supports BYOK. Follow the provider-specific requirements above and the live action contract.

## Prepare one reviewed input

Use one authorized record that matches the inspected schema. Preserve its source identity and define the result you will accept.

Open the action reference for its payload and response shape. Provider-backed execution can incur usage or external effects.

For reusable logic, follow [Write Plays](https://deepline.com/docs/sdk-v2/plays.md). For direct-call recovery, use [Tool execution recovery](https://deepline.com/docs/sdk-v2/tool-execution-recovery.md).

> [!TIP]
>
> Continue only when the workspace, provider, required fields, acceptance rule, and applicable price are understood. Keep unavailable access separate from no-result evidence.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.