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

# Manage templates and import LinkedIn profiles

> Save email template settings and queue bounded LinkedIn profile lookups, then reconcile durable operation and row results safely for your integration.

Use Emailx template endpoints to read or save email template settings. For a manual LinkedIn draft, you can queue a bounded lookup from profile URLs and inspect its durable operation and row outcomes. Template edits and LinkedIn URL imports alone do not generate or approve email content, activate a campaign, or send messages. CSV/XLSX People import is a separate workflow that saves contacts without enrolling them. For the separate reviewed LinkedIn activation flow, see [review and launch a LinkedIn campaign](https://docs.emailx.ai/en/overview/review-and-launch-linkedin.md).

> [!NOTE]
>
> Use a matching 0.8.0 API host, check workspace capabilities, and handle `503 feature_unavailable` as not enabled. This LinkedIn URL endpoint does not accept files; use the separate [People CSV/XLSX import](https://docs.emailx.ai/en/overview/people-import.md) workflow for contact files.

## Save template settings

Templates are workspace-scoped. Use `templates:read` to list or read them and `templates:write` to create or update them. The API exposes saved regular and smart template fields. It does not run prompts, generate personalized content, approve content, or attach a template to a campaign.

Create a template with the fields you need:

```bash theme={null}
curl -X POST "$EMAILX_BASE_URL/api/v1/workspaces/123/templates" \
  -H "Authorization: Bearer $EMAILX_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: crm-template-001" \
  --data '{"name":"Italian introduction","subject":"A quick introduction","body":"<p>Hello</p>","goal":"Sales"}'
```

List summaries with [GET `/templates`](https://docs.emailx.ai/en/api-reference/templates/list-templates). Read a full saved template with [GET `/templates/{template_id}`](https://docs.emailx.ai/en/api-reference/templates/get-template). The response includes an opaque `revision` that protects edits from overwriting newer changes.

To update, copy `revision` from a fresh GET into `expected_revision` and send only the changed fields:

```bash theme={null}
curl -X PATCH "$EMAILX_BASE_URL/api/v1/workspaces/123/templates/601" \
  -H "Authorization: Bearer $EMAILX_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: crm-template-002" \
  --data '{"expected_revision":"COPY_THE_CURRENT_REVISION","prompt":"Write a concise introduction."}'
```

On `409 stale_revision`, read the template again and reconcile your edit before submitting a new logical update. For a timeout or uncertain response, follow [idempotency and recovery](https://docs.emailx.ai/en/api-reference/idempotency.md). Do not treat a saved prompt or body as generated or approved copy.

## Queue a bounded LinkedIn URL import

The import endpoint accepts 1 to 100 profile objects per request. Each `linkedin_url` must be an HTTPS `linkedin.com/in/...` profile URL. Optional `first_name`, `last_name`, and `company` values provide row context. File uploads, CSV imports, provider search, and campaign targeting are not part of this endpoint.

Before submitting, read the campaign configuration and use its latest `revision` as `expected_revision`. Reading the configuration requires `campaigns:read`; the import write requires `campaigns:import`. The campaign must be an inactive, manual-source LinkedIn draft with autopilot disabled, no execution history, and the sender selected in its configuration. The sender must be active, authorized for the current actor, and included in the workspace plan. Agency access also requires `agency:read` and current workspace membership.

```bash theme={null}
curl -X POST "$EMAILX_BASE_URL/api/v1/workspaces/123/campaigns/linkedin/456/imports" \
  -H "Authorization: Bearer $EMAILX_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: crm-import-2026-11-001" \
  --data '{
    "expected_revision": "COPY_THE_CURRENT_CAMPAIGN_REVISION",
    "sender_id": 903,
    "leads": [
      {
        "linkedin_url": "https://www.linkedin.com/in/example-person/",
        "first_name": "Alex",
        "company": "Example Studio"
      }
    ]
  }'
```

The request returns `202` with an opaque operation ID. The request queues work; it does not resolve profiles inline. Provider lookups can consume the workspace's LinkedIn lookup quota. Keep each request within the 100-profile bound and account for that quota before submitting.

The HTTP request-body limit is 256 KiB, but the serialized durable command is limited to 64 KiB. Keep profile fields concise and split a larger list into separate, intentionally keyed imports; each request still accepts at most 100 profiles. Do not split or resubmit an import when its outcome is unknown.

> [!WARNING]
>
> Importing profiles does not activate the campaign or send connection requests or messages. Review imported prospects in Emailx before any separate app action.

## Poll operation and row results

Read the operation with [GET `/operations/{operation_id}`](https://docs.emailx.ai/en/api-reference/jobs/get-job). It reports a status and aggregate `result.counts`; `result.rows_path` points to the paginated row endpoint. Operation reads and row reads require `operations:read` plus `campaigns:read`.

```bash theme={null}
curl "$EMAILX_BASE_URL/api/v1/workspaces/123/operations/op_0123456789abcdef0123456789abcdef" \
  -H "Authorization: Bearer $EMAILX_API_KEY"
```

Follow `rows_path` and pass `next_cursor` unchanged to read later pages:

```bash theme={null}
curl "$EMAILX_BASE_URL/api/v1/workspaces/123/operations/op_0123456789abcdef0123456789abcdef/rows?limit=25" \
  -H "Authorization: Bearer $EMAILX_API_KEY"
```

Statuses include `queued`, `running`, `awaiting_user_action`, `succeeded`, `partially_succeeded`, `failed`, `needs_reconciliation`, and `cancelled`. A `needs_reconciliation` result or an uncertain response means the outcome needs review. Read the operation and its rows. If the POST response was lost and you do not have its operation ID, inspect [the workspace operation list](https://docs.emailx.ai/en/api-reference/jobs/list-jobs.md). Never automatically submit a second import or create a new idempotency key to force another attempt.

You can cancel an operation only while it is `queued` or `awaiting_user_action` and before an external effect starts. Cancellation requires `operations:write`, `campaigns:read`, and the original `campaigns:import` grant. If cancellation returns `409 operation_not_cancellable`, inspect operation and row results instead of retrying the import.

## Related API endpoints

* [List email templates](https://docs.emailx.ai/en/api-reference/templates/list-templates.md)
* [Create an email template](https://docs.emailx.ai/en/api-reference/templates/create-template.md)
* [Retrieve an email template](https://docs.emailx.ai/en/api-reference/templates/get-template.md)
* [Update an email template](https://docs.emailx.ai/en/api-reference/templates/update-template.md)
* [Create a LinkedIn import operation](https://docs.emailx.ai/en/api-reference/prospects/import-linkedin-profiles.md)
* [List operations](https://docs.emailx.ai/en/api-reference/jobs/list-jobs.md)
* [Read operation progress](https://docs.emailx.ai/en/api-reference/jobs/get-job.md)
* [Cancel an operation](https://docs.emailx.ai/en/api-reference/jobs/cancel-job.md)
* [Read import rows](https://docs.emailx.ai/en/api-reference/prospects/list-linkedin-import-results.md)


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