# set_destination_id

> Source: https://docs.clonepartner.com/reference/steps/set-destination-id/

<!-- sources: src/steps/set-destination-id-step.ts, src/steps/types.ts, references/envoy/patterns.md, references/envoy/step-types.md -->

# set_destination_id

Upserts a source-to-destination ID mapping into the mapping store and passes the input through unchanged.

## When to use it

Use `set_destination_id` right after a create step in the manual dedup pattern, paired with [get_destination_id](/reference/steps/get-destination-id/). For new tasks, prefer [sync_record](/reference/steps/sync-record/), which persists the mapping as part of one composite step.

## Configuration

| Key | Type | Required | Default | Description |
|---|---|---|---|---|
| `connector` | string | Yes | — | Connector slot for the mapping store. |
| `resource` | string | Yes | — | Resource or entity name the mapping is scoped to. |
| `source_id` | string | Yes | — | Source system ID. Coerced to a string. |
| `destination_id` | string | Yes | — | Destination system ID. Coerced to a string. |
| `hash` | string | No | — | Content hash stored alongside the mapping for change detection. |

## Example

```yaml
name: migrate-accounts
output: none
connectors:
  source:
    type: csv
  destination:
    type: dynamics365
  mapping_db:
    type: sqlite
steps:
  - name: read_accounts
    type: call_method
    config:
      connector: source
      method: read
      args:
        resource: accounts

  - name: create_account
    type: call_method
    config: |
      {
        "connector": "destination",
        "method": "create",
        "args": { "resource": "accounts", "data": input }
      }

  - name: store_mapping
    type: set_destination_id
    config: |
      {
        "connector": "mapping_db",
        "resource": "account",
        "source_id": steps.read_accounts.output.account_id,
        "destination_id": input.accountid
      }
```

Note that after `create_account`, `input` is the create response, so the source ID is read from the earlier step via `steps.read_accounts.output`.

## Behavior notes

- **Empty IDs are rejected loudly.** A `destination_id` that is undefined, null, an empty string, or the literal strings `"null"`/`"undefined"` fails the step with `set_destination_id: refusing to write empty destination_id ...`. An empty `source_id` fails the same way. Gate the step with `skip_if` when no real destination ID is available — for example when a preceding create with `error_handling: ignore` failed.
- **The input passes through unchanged** — the step writes the mapping and emits its input as-is.
- The mapping is written through the connector's mapping store, the same store [get_destination_id](/reference/steps/get-destination-id/) reads.

## Related

- [get_destination_id](/reference/steps/get-destination-id/) — the read half of the mapping pair
- [sync_record](/reference/steps/sync-record/) — the preferred composite replacement
- [Idempotent sync and the mapping DB](/building/idempotent-sync/) — mapping-store patterns and rerun safety
