---
title: "client.Shared"
description: "Every method in this namespace: its signature, its parameters, what it returns and an example."
url: "https://nextmail.sh/docs/csharp/reference/shared"
area: "C#"
category: "Reference"
---

# client.Shared

Every method in this namespace: its signature, its parameters, what it returns and an example.

## Methods

Templates, forms and automations shared at a public link by any workspace: read what the page of a link shows, from the token at its end, and copy the item into this workspace as a new draft when its owner lets people copy it.

### `Shared.GetAsync`

Read a template, form or automation shared at a public link

```csharp
Task<JsonObject> GetAsync(
    string token,
    string? apiKey = null,
    CancellationToken cancellationToken = default)
```

Returns what the public page of a link shows, from any workspace, this one included: the name and description of the item, the name of the workspace that shares it, whether it may be copied, and its content. Of `template`, `form` and `automation`, the one `kind` names is set and the other two are null.

A template comes rendered with the sample values of its props, as `subject`, `html` and `text`, and `unfilled` names the props and slots that have no sample value, so they render empty. A form comes with its design and whether it asks people to confirm their address. An automation comes with its flow, its settings and the template each send step sends. The audiences, addresses, forms and webhook endpoints an automation points at are left empty, and the audience choices of a form keep their labels only, because those belong to the owner.

Reading it here does not count as a view of the page.

Scopes: `templates:read`.

**Parameters**

- `token` (`string`, required): The token at the end of the public link: the `token` that `ShareLinks.GetAsync` returns for a link, or the last part of its `url`.
- `apiKey` (`string?`): Overrides the client's API key for this call only.
- `cancellationToken` (`CancellationToken`): Cancels the request.

**Returns**

A `JsonObject` with `object` set to `shared_item`, `kind`, `token`, `name`, `description`, `workspaceName`, `copyable`, `sharedAt`, `template`, `form` and `automation`. `template` holds `subject`, `engine`, `slots`, `props`, `html`, `text` and `unfilled`, `form` holds `document` and `doubleOptIn`, and `automation` holds `definition`, `templates` and `settings`. `workspaceName` is empty when the workspace has no name, and `sharedAt` is when the item was made public at this link.

**Example**

```csharp
var item = await client.Shared.GetAsync("9c4e2a7f1b6d3e8a0f5c2b7d4e1a9f36");

Console.WriteLine($"The {item["kind"]} {item["name"]} from {item["workspaceName"]}{((bool?)item["copyable"] == true ? ", free to copy" : string.Empty)}");

if (item["template"] is { } template)
{
    Console.WriteLine($"{template["subject"]}, with no sample value for {template["unfilled"]?.AsArray().Count ?? 0} props");
}
```

**Notes**

- Reading it takes the read scope of the kind of the item: `templates:read`, `forms:read` or `automations:read`. A key with none of the three is refused with 403 `insufficient_scope` before the link is looked up, and a key without the one the item needs is refused once it is found.
- A token that no public link has is a 404 `shared_item_not_found`, and so is the link of an item its owner made private or deleted.
- Read only, so the SDK retries it after a network failure like any other read.

Also available in: API [`GET /shared/{token}`](https://nextmail.sh/docs/api/reference/sharing#get-shared-token); TypeScript [`shared.get()`](https://nextmail.sh/docs/sdk/reference/shared#get); Python [`shared.get()`](https://nextmail.sh/docs/python/reference/shared#get); Ruby [`shared.get`](https://nextmail.sh/docs/ruby/reference/shared#get); PHP [`shared->get`](https://nextmail.sh/docs/php/reference/shared#get); Go [`Shared.Get`](https://nextmail.sh/docs/go/reference/shared#get); Java [`shared().get`](https://nextmail.sh/docs/java/reference/shared#get); CLI [`nextmail shared get`](https://nextmail.sh/docs/cli/reference/shared#shared-get).

### `Shared.CopyAsync`

Copy a shared template, form or automation into this workspace

```csharp
Task<JsonObject> CopyAsync(
    string token,
    string? apiKey = null,
    CancellationToken cancellationToken = default)
```

Copies the item at a public link into this workspace as a new draft, as Copy to my workspace does on the page, and returns the copy. The copy counts in `copies` on the link, and it is an item of its own, so later changes on either side never reach the other.

A template whose name is taken here gets a number after it, and the images it shows are copied into this workspace. An automation brings the templates its send steps send, copied as new templates and listed in `templateIds`, and its steps send those copies.

A copy carries the design only: never the submissions, sends, runs or contacts the original collected, and never the audiences, addresses, forms or webhook endpoints it points at. Those stay with the owner and are left empty for you to fill in.

Scopes: `templates:write`.

**Parameters**

- `token` (`string`, required): The token at the end of the public link: the `token` that `ShareLinks.GetAsync` returns for a link, or the last part of its `url`.
- `apiKey` (`string?`): Overrides the client's API key for this call only.
- `cancellationToken` (`CancellationToken`): Cancels the request.

**Returns**

A `JsonObject` with `object` set to `shared_copy`, `kind`, `id`, `name` and `templateIds`, answered with status 201. `id` is the new template, form or automation, a draft here, `name` the name it got, and `templateIds` the templates copied along with an automation, empty for the rest.

**Example**

```csharp
try
{
    var copy = await client.Shared.CopyAsync("9c4e2a7f1b6d3e8a0f5c2b7d4e1a9f36");

    Console.WriteLine($"Copied as the {copy["kind"]} {copy["id"]}, named {copy["name"]}");

    var templateIds = copy["templateIds"]?.AsArray() ?? [];

    if (templateIds.Count > 0)
    {
        Console.WriteLine($"Templates copied with it: {string.Join(", ", templateIds)}");
    }
}
catch (NextmailApiException error) when (error.Code == "share_not_copyable")
{
    Console.WriteLine("Its owner shares it to look at, not to copy");
}
```

**Notes**

- Copying takes the write scope of the kind of the item, and an automation that sends templates also takes `templates:write`. A key without them is refused with 403 `insufficient_scope`, and nothing is copied.
- An item its owner shares to look at, not to copy, is a 403 `share_not_copyable`. A token that no public link has, or the link of an item made private or deleted, is a 404 `shared_item_not_found`.
- Workspace limits apply as they do to anything created here, so a workspace that already holds as many templates, forms or automations as it may answers 422 `workspace_limit_reached`. Nothing is kept then: the templates copied for an automation are removed again when the automation cannot be made.
- Not retried by the SDK, because a second call makes a second copy. A retry by hand after a lost response can leave two copies, so list them and delete the spare.

Also available in: API [`POST /shared/{token}/copy`](https://nextmail.sh/docs/api/reference/sharing#post-shared-token-copy); TypeScript [`shared.copy()`](https://nextmail.sh/docs/sdk/reference/shared#copy); Python [`shared.copy()`](https://nextmail.sh/docs/python/reference/shared#copy); Ruby [`shared.copy`](https://nextmail.sh/docs/ruby/reference/shared#copy); PHP [`shared->copy`](https://nextmail.sh/docs/php/reference/shared#copy); Go [`Shared.Copy`](https://nextmail.sh/docs/go/reference/shared#copy); Java [`shared().copy`](https://nextmail.sh/docs/java/reference/shared#copy); CLI [`nextmail shared copy`](https://nextmail.sh/docs/cli/reference/shared#shared-copy).
