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

# Save a backlink contact

> Create or replace a private backlink contact by its stable externalRef at an expected revision (0 creates).

`save_contact`

Create or replace a private backlink contact by its stable externalRef at an expected revision (0 creates). Identical replay is a no-op; no outreach is sent.

> [!NOTE]
>
> Name recorded in the 2026-10-27 deployment. This page describes current source; verify inputs and access in your connected catalog. Provider configuration and workspace access still apply.

| Access | Behavior |
| - | - |
| `watches:write` | Writes or admits work; can change or remove existing state |

## Example request

Connect through [MCP](https://docs.agentlinkops.com/guides/connect-mcp.md), [CLI](https://docs.agentlinkops.com/guides/connect-cli.md), or [HTTP](https://docs.agentlinkops.com/guides/connect-http.md). Replace example identifiers with records from your workspace.

```json MCP theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "save_contact",
    "arguments": {
      "projectId": "project_example",
      "revision": 0,
      "contact": {
        "externalRef": "source:publisher",
        "name": "Example publisher",
        "email": "editor@publisher.example",
        "contactUrl": null
      }
    }
  }
}
```

```bash CLI theme={null}
agentlinkops call save_contact --args '{"projectId":"project_example","revision":0,"contact":{"externalRef":"source:publisher","name":"Example publisher","email":"editor@publisher.example","contactUrl":null}}'
```

```bash HTTP theme={null}
curl --fail-with-body https://app.agentlinkops.com/v1/commands/save_contact \
  -H "Authorization: Bearer $AGENTLINKOPS_TOKEN" \
  -H 'Content-Type: application/json' \
  --data '{"projectId":"project_example","revision":0,"contact":{"externalRef":"source:publisher","name":"Example publisher","email":"editor@publisher.example","contactUrl":null}}'
```

## Returned result

Schema-validated example; IDs and dates are illustrative. MCP returns this data in `structuredContent` and in a text content block; generic HTTP and CLI return the JSON result directly.

```json theme={null}
{
  "contact": {
    "id": "contact_example",
    "projectId": "pr_example",
    "externalRef": "outreach:example:publisher",
    "name": "Example publisher",
    "email": null,
    "contactUrl": null,
    "revision": "e61fed8c-85c3-4f30-a4d8-d84934f27698",
    "createdAt": "2026-09-13T12:00:00.000Z",
    "updatedAt": "2026-09-13T12:00:00.000Z"
  },
  "replayed": false
}
```

## Input fields

Omit optional fields when you do not want to supply them. Null is accepted only where listed. Unknown input properties are rejected.

| Field | Type | Presence | Meaning and constraints |
| - | - | - | - |
| `projectId` | string | Required | project ID from create/list. minLength: `1`; maxLength: `200` |
| `revision` | number / string | Required | Current contact revision from list\_contacts or save\_contact; 0 creates. |
| `contact` | object | Required | additional fields rejected |
| `contact.externalRef` | string | Required | minLength: `1`; maxLength: `200` |
| `contact.name` | string | Required | minLength: `1`; maxLength: `120` |
| `contact.email` | string / null | Required | |
| `contact.contactUrl` | string / null | Required | |
| `acceptTermsVersion` | string | Optional | Supply the current terms version only after an owner or administrator explicitly agrees for everyone saving contacts on this website. Never infer agreement from an import or contact read. minLength: `1`; maxLength: `80` |

### Validation and omitted values

The stable identity is workspace, project and externalRef. Use revision 0 to create; use the current opaque revision to replace all four supplied fields. Identical content replays without a contact write, subject to the current contact terms.

Email and contact-page fields may be null. Saving a contact changes no sender record, sequence, watch schedule or verification job.

If access changes after a save commits, the response may fail despite a saved record. Retain externalRef and intended content; read list\_contacts when authorized before reconciling. A failed response does not prove no write.

When a contact terms policy is active, list\_contacts returns its current version and acceptance state. Only a current workspace owner or administrator may supply acceptTermsVersion after explicitly agreeing for everyone who saves contacts on that website. Never infer agreement from a read or import. The acknowledgment may commit before a later contact save fails; reread list\_contacts.terms before reconciling. Reads, export, deletion and clearing a link's contact stay available without acceptance.

## Output fields

Fields inside optional or nullable parents apply only when that parent exists. [Common schema conventions](https://docs.agentlinkops.com/reference/schemas.md) explain evidence states, empty lists and extensions.

* **`contact`** (object, required).
* **`replayed`** (boolean, required): True when the response reuses an earlier request with the same idempotency value.

> **All fields and nested objects**
>
> Types, allowed values, limits and nested fields:
>
> | Field | Type | Presence | Meaning and constraints |
> | - | - | - | - |
> | `contact` | object | Required | additional fields rejected |
> | `contact.externalRef` | string | Required | minLength: `1`; maxLength: `200` |
> | `contact.name` | string | Required | minLength: `1`; maxLength: `120` |
> | `contact.email` | string / null | Required | |
> | `contact.contactUrl` | string / null | Required | |
> | `contact.id` | string | Required | Resource identifier returned by the operation. minLength: `1`; maxLength: `200` |
> | `contact.projectId` | string | Required | Identifier returned by the related operation. minLength: `1`; maxLength: `200` |
> | `contact.revision` | string | Required | Revision of this saved contact. Supply it as revision when updating or deleting the contact. format: `"uuid"`; pattern: `"^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}\|00000000-0000-0000-0000-000000000000\|ffffffff-ffff-ffff-ffff-ffffffffffff)$"` |
> | `contact.createdAt` | string | Required | |
> | `contact.updatedAt` | string | Required | |
> | `contact.attention` | object / null | Optional | |
> | `contact.relatedRecords` | array | Optional | |
> | `contact.relatedRecords[].watchId` | string | Required | Identifier returned by the related operation. minLength: `1`; maxLength: `200` |
> | `contact.relatedRecords[].sourceUrl` | string / null | Required | |
> | `contact.relatedRecords[].publisherUrl` | string | Required | |
> | `contact.relatedRecords[].targetUrl` | string | Required | |
> | `contact.relatedRecords[].progress` | string / null | Required | |
> | `contact.relatedRecords[].monitoring` | boolean | Required | |
> | `contact.relatedRecords[].participationId` | string | Optional | Identifier returned by the related operation. minLength: `1`; maxLength: `200` |
> | `contact.relatedRecords[].campaign` | string | Optional | |
> | `contact.relatedRecords[].lastContactedAt` | string / null | Optional | |
> | `contact.hasMoreRelatedRecords` | boolean | Optional | |
> | `replayed` | boolean | Required | True when the response reuses an earlier request with the same idempotency value. |

[Download input schema](https://docs.agentlinkops.com/schemas/save_contact.input.json) · [Download output schema](https://docs.agentlinkops.com/schemas/save_contact.output.json)

## Errors and retries

This write is annotated idempotent without a caller-supplied idempotency key. Reconcile saved state after an uncertain response, then use the same inputs for the same intended operation. Do not add an unsupported key.

See [error recovery](https://docs.agentlinkops.com/reference/errors.md) for status, scope, cooldown, cursor and retry handling. Unknown observations are result data and do not establish loss.

## HTTP resource routes

This operation has no separate resource alias. Use its generic command route in a matching environment.

## Continue

[list\_contacts](https://docs.agentlinkops.com/reference/commands/list_contacts.md) · [set\_link\_contact](https://docs.agentlinkops.com/reference/commands/set_link_contact.md)

Follow the [related workflow](https://docs.agentlinkops.com/guides/monitor-changes.md). See [capability status](https://docs.agentlinkops.com/capability-status.md) for availability or the [command index](https://docs.agentlinkops.com/reference/index.md) for another operation.


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