# People

Part of the [Ownbox SDK reference](https://www.ownbox.io/sdk/reference.md).

## m.person

```python
m.person(kind, value, *, name='', space=None)
```

The person behind an id.

Made the first time any machine meets them. `kind` is how you know them: "email", "phone", "instagram", "messenger", "facebook", "prospect" or "web". `space` matters only on an Ownbox that runs more than one business. Never raises.

**Needs in machine.yaml:** `data: [people:write]`

**Returns:** Their person id, the same whichever machine asks, or None for an id that isn't one.

Example (inside a job):

```python
pid = m.person("email", "ava@example.com", name="Ava Reyes")
```

## m.touch

```python
m.touch(person, kind, ref='')
```

Record what happened to a person.

`kind` is lowercase letters and underscores ("quote_sent", "booked"); a step or a campaign goes in `ref`. The same thing told twice is recorded once. Never raises.

**Needs in machine.yaml:** `data: [people:write]`

**Returns:** True, or False for a bad call or a repeat.

Example (inside a job):

```python
pid = m.person("email", "ava@example.com")
m.touch(pid, "quote_followed_up", ref="quote-41")
```

## m.people_find

```python
m.people_find(q=None, *, kind=None, limit=50, cursor=None, space=None)
```

The people this business met, a page at a time.

With no question, everyone, in the order they were met, 50 at a time: pass `next` back as `cursor` for the next page. With one, `m.people_find("ava@example.com", kind="email")`, the one person behind an id. Never raises.

**Needs in machine.yaml:** `data: [people:read]`

**Returns:** `{"people": [{"id", "name", "ids": [{"kind", "value"}], "first_seen_at", "first_seen_by"}], "next"}`. `next` is "" at the end.

Example (inside a job):

```python
page = m.people_find(limit=20)
names = [p["name"] for p in page["people"]]
```

## m.people_timeline

```python
m.people_timeline(person, *, limit=50, cursor=None)
```

What happened to one person, newest first.

Across every machine on the Ownbox. Pass `cursor` back for older events. Never raises.

**Needs in machine.yaml:** `data: [people:read]`

**Returns:** `{"events": [{"at", "machine", "kind", "ref"}], "next"}`.

Example (inside a job):

```python
first = m.people_find(limit=1)["people"]
if first:
    events = m.people_timeline(first[0]["id"], limit=10)["events"]
```

## on_forget

```python
on_forget(person_id)
```

Erase one person from the machine's own data.

Not a call: a function the machine defines, beside `m`. A machine whose machine.yaml names people data (`people:read` or `people:write`) must also say `on_forget: true`, or the Ownbox refuses it. `on_forget` removes that person from the machine's own settings and files, and returns True once they are gone. Not called yet: the Ownbox does not call a custom machine's `on_forget` today, so erasing a person on the Ownbox does not reach this machine's own data until it does. Write it now; the machine is refused without it.

**Needs in machine.yaml:** `on_forget: true`, beside `permissions:`

**Returns:** True once the person is gone from the machine.

Example (where the machine is defined):

```python
def on_forget(person_id):
    asked = dict(m.setting("asked", default={}) or {})
    if asked.pop(str(person_id), None) is not None:
        m.save_setting("asked", asked)
    return True
```

