# Thing routes: relate, resolve, restore

URL: /code/api/thing/verbs · Id: `page:code/api/thing/verbs`

> The Thing Verbs relate, resolve, restore as api.sb routes, with inputs, result, refusals and an example.

Reference for [Thing](/business/nouns/thing), one group of [Thing routes](/code/api/thing).

### Thing.relate
Relate links two Things by a Relationship their Nouns declare, readable from both ends at once. [Verb page](/business/nouns/thing/relate?interface=api).

```text
POST /{namespace}/things/{thing}/relate
```

Path: `thing`. Body, as JSON: the other inputs. Emits [`Thing.related`](/business/events/Thing.related).

**Inputs**

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `thing` | [Thing](/business/nouns/thing) | Yes | The source Thing. |
| `predicate` | `string` | Yes | The Relationship as read from the source, such as `places`. |
| `to` | [Thing](/business/nouns/thing) | Yes | The target Thing. |

**Returns**

| Output | Type | Required | Description |
| --- | --- | --- | --- |
| `relationship` | [Relationship](/business/nouns/relationship) | Yes | The Relationship, with its provenance. |
| `thing` | [Thing](/business/nouns/thing) | Yes | The Thing the Relationship starts from. |

**Refuses when**

| Check | Error | Fix | Then call |
| --- | --- | --- | --- |
| The key is valid, but its scopes do not allow this operation. | [`forbidden`](/code/api/errors/forbidden) | Use a key whose scopes cover the operation, or ask an owner of the namespace to grant them. | None. |
| A predicate that neither Noun declares | [`refused`](/code/api/errors/refused) | Clear what the check names, then call it again. | None. |

**Example**

```bash
curl -X POST https://api.sb/leaseline.app/things/thing_8ds0r9vvRl/relate \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"predicate":"Example predicate","to":"thing_8ds0r9vvRl"}'
```

```json
{
  "api": "https://api.sb/leaseline.app",
  "relationship": {
    "$id": "https://api.sb/leaseline.app/relationships/relationship_iUVcHztTJh",
    "$type": "Relationship",
    "predicate": "Example predicate",
    "inverse": "Example inverse"
  },
  "thing": {
    "$id": "https://api.sb/leaseline.app/things/thing_8ds0r9vvRl",
    "$type": "Thing",
    "id": "Example id",
    "type": [
      "noun_v0akLUrXCN"
    ]
  },
  "action": {
    "$id": "https://api.sb/leaseline.app/actions/act_br07HsG8MG",
    "operation": "Thing.relate",
    "status": "done"
  },
  "links": {
    "self": "https://api.sb/leaseline.app/actions/act_br07HsG8MG"
  }
}
```

### Thing.resolve
Resolve finds the one Thing of a Noun that matches given properties, or creates it, and says which it did. [Verb page](/business/nouns/thing/resolve?interface=api).

```text
POST /{namespace}/things/resolve
```

Body, as JSON: the inputs. Emits [`Thing.resolved`](/business/events/Thing.resolved).

**Inputs**

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `noun` | [Noun](/business/nouns/noun) | Yes | The Noun to resolve. |
| `match` | `json` | Yes | The properties that identify the Thing, such as an email address. |
| `set` | `json` | No | Properties to write on the found or created Thing. |

**Returns**

| Output | Type | Required | Description |
| --- | --- | --- | --- |
| `thing` | [Thing](/business/nouns/thing) | No | The Thing found or created; empty when held. |
| `decision` | `string` | Yes | What happened: `found`, `created`, or `held` when two or more Things match. |

**Refuses when**

| Check | Error | Fix | Then call |
| --- | --- | --- | --- |
| The key is valid, but its scopes do not allow this operation. | [`forbidden`](/code/api/errors/forbidden) | Use a key whose scopes cover the operation, or ask an owner of the namespace to grant them. | None. |

**Example**

```bash
curl -X POST https://api.sb/leaseline.app/things/resolve \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"noun":"noun_v0akLUrXCN","match":{}}'
```

```json
{
  "api": "https://api.sb/leaseline.app",
  "thing": {
    "$id": "https://api.sb/leaseline.app/things/thing_8ds0r9vvRl",
    "$type": "Thing",
    "id": "Example id",
    "type": [
      "noun_v0akLUrXCN"
    ]
  },
  "decision": "found",
  "action": {
    "$id": "https://api.sb/leaseline.app/actions/act_br07HsG8MG",
    "operation": "Thing.resolve",
    "status": "done"
  },
  "links": {
    "self": "https://api.sb/leaseline.app/actions/act_br07HsG8MG"
  }
}
```

### Thing.restore
Restore brings back a deleted Thing, or one an undone Action removed, with its history and Relationships intact. [Verb page](/business/nouns/thing/restore?interface=api).

```text
POST /{namespace}/things/{thing}/restore
```

Path: `thing`. Emits [`Thing.restored`](/business/events/Thing.restored).

**Inputs**

| Input | Type | Required | Description |
| --- | --- | --- | --- |
| `thing` | [Thing](/business/nouns/thing) | Yes | The deleted Thing. |

**Returns**

| Output | Type | Required | Description |
| --- | --- | --- | --- |
| `thing` | [Thing](/business/nouns/thing) | Yes | The Thing, back in every list and query it left. |

**Refuses when**

| Check | Error | Fix | Then call |
| --- | --- | --- | --- |
| The key is valid, but its scopes do not allow this operation. | [`forbidden`](/code/api/errors/forbidden) | Use a key whose scopes cover the operation, or ask an owner of the namespace to grant them. | None. |
| The Thing is not deleted | [`refused`](/code/api/errors/refused) | Clear what the check names, then call it again. | None. |

**Example**

```bash
curl -X POST https://api.sb/leaseline.app/things/thing_8ds0r9vvRl/restore \
  -H "Authorization: Bearer $STARTUP_BUILDER_API_KEY"
```

```json
{
  "api": "https://api.sb/leaseline.app",
  "thing": {
    "$id": "https://api.sb/leaseline.app/things/thing_8ds0r9vvRl",
    "$type": "Thing",
    "id": "Example id",
    "type": [
      "noun_v0akLUrXCN"
    ]
  },
  "action": {
    "$id": "https://api.sb/leaseline.app/actions/act_br07HsG8MG",
    "operation": "Thing.restore",
    "status": "done"
  },
  "links": {
    "self": "https://api.sb/leaseline.app/actions/act_br07HsG8MG"
  }
}
```