# Record entries in a session

> Record entries in one of your sessions: up to 200 at a time, each with kind (prompt, message, tool_call, tool_result, note, or skill for a skill it used, by name), text (up to 64,000 characters), and for tools tool.

<div class="g1t-endpoint"><span class="g1t-method" data-method="post">POST</span><code>/repos/{owner}/{name}/sessions/{id}/entries</code></div>

Give each a `key` and recording it again does nothing, so a retried hook records it once. `touched` says what it touched, up to 200: `{ kind, value }` with kind file (a path from the repository's root), commit, branch, pull (one it opened) or issue (one it named); each is kept once, ties the session to the pull requests and issues it names, and a file another active session touched too (outside its own parents and subagents, so siblings yes) is an overlap.detected event for both, once per pair and again when a file it was not announced for joins. Entries of a session attached to a pull request show in that pull request's session too, where reviewers read why the change is what it is. `acknowledge` accepts up to 100 exact pending update IDs this session has considered; reading alone never acknowledges. Recording is a heartbeat. Returns how many were `recorded`, how many were `duplicates`, and how many of the `acknowledge` IDs were `acknowledged` (fewer than given means some were not this session's updates).

Up to 200 entries a request. An entry whose `key` the session recorded before is counted in `duplicates` and not recorded again. Entries of a session on a pull request show in that pull request's session too ([`read_session`](/reference/api/sessions/read-session/)). `acknowledge` (up to 100 update IDs from get_session's `updates`) clears those updates for this session only; `acknowledged` counts the IDs that were this session's.

- **Authentication:** Required. Send an [access token](/reference/api/#authentication) as `Authorization: Bearer`.
- **MCP tool:** [`session`](/reference/mcp/#session) with `action` `record`, and the same inputs
- **Scope:** An access token needs [`pull_requests:write`](/guides/authentication/#scopes).

## Path parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `owner` | string | Yes | The workspace that owns the repository. |
| `name` | string | Yes | The repository's name. |
| `id` | string | Yes | The session's id (ses_…), from [`start_session`](/reference/api/sessions/start-session/) or [`list_sessions`](/reference/api/sessions/list-sessions/). |

## Body parameters

Send a JSON object. Names are `snake_case`, as in responses; the `camelCase` spelling is accepted too.

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `acknowledge` | array of strings | No | Exact pending update IDs this session has considered; never acknowledge merely because fetched. |
| `entries` | array of objects | No | Up to 200 entries, oldest first. |
| `entries[].kind` | string | Yes | One of `prompt`, `message`, `tool_call`, `tool_result`, `note`, `skill`. |
| `entries[].text` | string | Yes | For a skill, its name only. |
| `entries[].tool` | string | No | For tool_call and tool_result: the tool's name. |
| `entries[].commit` | string | No | The commit it was recorded at; the session's head if left out. |
| `entries[].key` | string | No | An idempotency key, unique in the session: an entry with a key recorded before is skipped. |
| `touched` | array of objects | No | What it touched, up to 200, each kept once. |
| `touched[].kind` | string | Yes | One of `file`, `commit`, `branch`, `pull`, `issue`. |
| `touched[].value` | string | Yes | A path from the repository's root, a commit, a branch, or a number. |

## Example request

```sh
curl -X POST https://api.g1t.sh/repos/flagon-io/hello/sessions/id/entries \
  -H "Authorization: Bearer $G1T_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "entries": [
      {
        "kind": "prompt",
        "text": "Make the greeting name the caller (issue #12).",
        "key": "prompt-1"
      },
      {
        "kind": "tool_call",
        "text": "cargo test",
        "tool": "Bash",
        "key": "tool-7"
      },
      {
        "kind": "skill",
        "text": "work-on-issue",
        "key": "skill-3"
      }
    ],
    "touched": [
      {
        "kind": "file",
        "value": "src/greet.rs"
      },
      {
        "kind": "branch",
        "value": "greet-caller"
      }
    ]
  }'
```

## Example response

A successful request answers `200` with:

```json
{
  "recorded": 3,
  "duplicates": 0,
  "acknowledged": 0
}
```

## Errors

A failed request answers with one of these statuses and a body like `{"error": {"code": "not_found", "message": "Repository not found."}}`. See [errors](/reference/api/#errors).

| Status | Code | When |
| --- | --- | --- |
| 401 | `unauthenticated` | A token is required, or the one sent is not valid. |
| 403 | `forbidden` | The token is valid but not allowed to do this, such as a member-only change, or a token without the scope it needs. |
| 404 | `not_found` | It does not exist, or you cannot see it. |
| 409 | `conflict` | The request conflicts with the current state. |
| 422 | `invalid` | The input is not valid. `message` says which field and why. |
