# Your own ids

> Send a record again under your own id, and Geniffy updates it, learning only what changed.

When your app syncs its own records, such as tickets, CRM notes, documents or a conversation that keeps
growing, give each one its id. Send it again under the same `external_id` and Geniffy updates the source
it already holds instead of adding a second one.

```python
mem.memories.add(ticket.body, title=ticket.subject, external_id=f"ticket-{ticket.id}")
```

```ts
await mem.memories.add({ text: ticket.body, title: ticket.subject, externalId: `ticket-${ticket.id}` });
```

```bash
curl https://api.geniffy.com/v1/memories \
  -H "Authorization: Bearer $GENIFFY_API_KEY" \
  -H "X-Geniffy-Space: customer_1042" \
  -H "Content-Type: application/json" \
  -d '{"text": "Asha asked about invoice 7.", "title": "Ticket 42", "external_id": "ticket-42"}'
```

## What a send does

- **Nothing changed:** nothing is learned again. The source comes back as it was, still `learned`.
- **Something changed:** the same source, under the same id, starts `reading` again. Only the paragraphs
  that changed are learned, and what was removed is taken back, so a fact you deleted from the record stops
  being recalled.
- **It is now another kind**, such as a note sent again as a web page: the old source is replaced whole.
- **A file or page that can't be read** this time keeps what the source held before, and the call says why.

This works the same for a note, a conversation, a web page, a file (`external_id` as a form field), and each
item of a [batch](https://docs.geniffy.com/add-memories/many-at-once).

## A conversation that grows

Send the whole conversation after each turn, under the conversation's id. It stays one source, and each send
learns only the new turns.

```python
mem.memories.add(messages=history, external_id=f"chat-{conversation.id}")
```

```ts
await mem.memories.add({ messages: history, externalId: `chat-${conversation.id}` });
```

## Find it, or delete it, by your id

```python
mem.sources.get(external_id="ticket-42")       # the source, with how learning went
mem.sources.delete(external_id="ticket-42")    # when the ticket is deleted in your app
```

```ts
await mem.sources.get({ externalId: "ticket-42" });
await mem.sources.delete({ externalId: "ticket-42" });
```

Over HTTP: `GET /v1/sources?external_id=ticket-42` and `DELETE /v1/sources?external_id=ticket-42`. Deleting
takes the source and every memory only it taught. A lookup that finds nothing is a `404`.

## The rules for an id

- Up to 300 characters, and anything your app already uses: a database id, a path, a URL.
- One id names one source in each space. Two of your users can each have a `ticket-42`.
- A blank id, or one with a line break, is refused with `bad_external_id`. Leave `external_id` out to add a
  source that is never updated.

Source: https://docs.geniffy.com/add-memories/your-own-ids
