> For the complete documentation index, see [llms.txt](https://docs.spike.sh/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.spike.sh/spike-api-docs/notes.md).

# Notes

Read and write the notes on an incident with an API key — add a note or a resolution note, pin the one that says where the response is right now, and archive one. A note written this way is attributed to the API key and reads as `<key name> (API)`, so an automation never needs a teammate’s credentials.

## Add a note to an incident

> Write a note on an incident.\
> \
> This endpoint authenticates an organisation, not a person. The note is\
> attributed to the API key that wrote it, and reads on the incident as\
> \`\<key name> (API)\` — so a note no human wrote never looks as though one\
> did, and an in-house agent can write on an incident without being handed\
> a teammate's credentials.\
> \
> \`content\` is stored and returned verbatim, so Markdown passes through\
> untouched.\
> \
> \### Params:\
> \
> \`content\*\`: The body of the note. Up to 10000 characters.\
> \
> \`isResolution\`: \`true\` records the note as a resolution note — what\
> fixed the incident, rather than a comment on it. Defaults to \`false\`.\
> \
> \\\* Required\
> \
> No \`x-team-id\` is needed: the organisation comes from the API key, and\
> the incident already names its team.\
> \
> To pin the new note as the incident's current state, follow this with\
> \`PUT /incidents/{counterId}/notes/{noteId}/pin\`.\
> \
> Attachments are deliberately not part of this API — a note written by a\
> non-user identity cannot carry an uploaded file. Attach files from the\
> dashboard.

```json
{"openapi":"3.1.0","info":{"title":"Spike API","version":"1.0.0"},"tags":[{"name":"Notes","description":"Read and write the notes on an incident with an API key — add a note or a resolution note, pin the one that says where the response is right now, and archive one. A note written this way is attributed to the API key and reads as `<key name> (API)`, so an automation never needs a teammate’s credentials."}],"servers":[{"url":"https://api.spike.sh","description":"API server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"Your organisation's API key. Create one in the Spike dashboard under Settings > API. Sent on every request as the `x-api-key` header."}},"schemas":{"IncidentNote":{"type":"object","description":"A note on an incident — what responders write on the incident as they work it.","properties":{"_id":{"type":"string","description":"The note's id. Pin or archive the note by this id."},"content":{"type":["string","null"],"description":"The body of the note, exactly as it was sent. Markdown is stored and returned verbatim — the API never converts or sanitises it, so what renders it decides how it reads. `null` on an archived note, whose body is hidden from everyone but its author."},"isResolution":{"type":"boolean","description":"`true` when the note records what resolved the incident rather than a comment on it."},"archived":{"type":"boolean","description":"`true` when the note has been archived. Archiving is a reversible soft-hide, not a delete: the note stays visible to its author, who can restore it from the dashboard, and everyone else sees an audit line in its place."},"author":{"type":["object","null"],"description":"Who wrote the note, named the way every Spike surface names an actor. A note written through this API carries the API key that wrote it; a note a person wrote in the dashboard, Slack or the mobile app carries that user.","properties":{"type":{"type":"string","enum":["api-key","user"],"description":"Whether an API key or a person wrote the note."},"_id":{"type":"string","description":"The id of the API key or the user."},"name":{"type":"string","description":"How the author reads on an incident. A person's first name; an API key as `<key name> (API)`, for example `Internal key (API)`, so a note no human wrote never reads as though one did. A key with no name reads `Untitled (API)`."}}},"counterId":{"type":"string","description":"The `counterId` of the incident the note belongs to."},"incident":{"type":"string","description":"The `_id` of the incident the note belongs to."},"editedAt":{"type":["string","null"],"description":"When the note was last edited, or `null` if it never was. Only a note's own author may edit one, so a note written by an API key is never edited."},"createdAt":{"type":"string","description":"When the note was written."},"updatedAt":{"type":"string","description":"When the note last changed."}}},"Error":{"type":"object","properties":{"message":{"type":"string","description":"Error message describing the problem"},"error":{"type":"string","description":"Error type or code"},"success":{"type":"boolean","description":"Present on the endpoints whose handlers include it (for example the API-key filter and the public on-call routes). Always `false` on an error."},"valid_api":{"type":"boolean","description":"Present on `401`s produced by the session/API-key filter. `false` means the supplied `x-api-key` was not recognised."},"statusCode":{"type":"number","description":"Echo of the HTTP status, present on a few permission errors."},"status":{"type":"boolean","description":"Present on the status-page component write endpoints, which answer a rejected write `{status: false, error, message}`. Always `false` on an error."}}}}},"paths":{"/incidents/{counterId}/notes":{"post":{"operationId":"postIncidentsByCounterIdNotes","summary":"Add a note to an incident","description":"Write a note on an incident.\n\nThis endpoint authenticates an organisation, not a person. The note is\nattributed to the API key that wrote it, and reads on the incident as\n`<key name> (API)` — so a note no human wrote never looks as though one\ndid, and an in-house agent can write on an incident without being handed\na teammate's credentials.\n\n`content` is stored and returned verbatim, so Markdown passes through\nuntouched.\n\n### Params:\n\n`content*`: The body of the note. Up to 10000 characters.\n\n`isResolution`: `true` records the note as a resolution note — what\nfixed the incident, rather than a comment on it. Defaults to `false`.\n\n\\* Required\n\nNo `x-team-id` is needed: the organisation comes from the API key, and\nthe incident already names its team.\n\nTo pin the new note as the incident's current state, follow this with\n`PUT /incidents/{counterId}/notes/{noteId}/pin`.\n\nAttachments are deliberately not part of this API — a note written by a\nnon-user identity cannot carry an uploaded file. Attach files from the\ndashboard.","tags":["Notes"],"parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"},"description":"Your API key. Find it in your Spike dashboard under Settings > API."},{"name":"counterId","in":"path","required":true,"schema":{"type":"string"},"description":"The incident's `counterId` — the short identifier in the incident's URL, and the `counterId` field of `GET /incidents`."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["content"],"properties":{"content":{"type":"string","description":"The body of the note, Markdown or plain text. Stored verbatim. Up to 10000 characters."},"isResolution":{"type":"boolean","default":false,"description":"Record the note as a resolution note — what fixed the incident, rather than a comment on it."}}}}}},"responses":{"201":{"description":"The note was written.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"note":{"$ref":"#/components/schemas/IncidentNote"}}}}}},"400":{"description":"`content` was missing, blank, not a string, or longer than 10000 characters. Nothing was written.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No incident with that `counterId` in your organisation. An incident belonging to another organisation reads the same way.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Read an incident's notes

> Read every note on an incident, oldest first, with the pinned one named\
> separately.\
> \
> An archived note is included with \`archived: true\` and \`content: null\`.\
> Archiving hides a note's body from everyone except its author, and an\
> API key is nobody's author, so this never returns an archived body — the\
> same stub a teammate who did not write it sees.\
> \
> \`pinnedNote\` is the \`\_id\` of the note that answers "where are we right\
> now", or \`null\`. One note is pinned at a time.\
> \
> The path is \`/notes/list\` rather than \`/notes\` because\
> \`GET /incidents/{counterId}/notes\` is the dashboard's own endpoint and\
> returns the dashboard's envelope. It is left alone so nothing already\
> reading it changes under them.

```json
{"openapi":"3.1.0","info":{"title":"Spike API","version":"1.0.0"},"tags":[{"name":"Notes","description":"Read and write the notes on an incident with an API key — add a note or a resolution note, pin the one that says where the response is right now, and archive one. A note written this way is attributed to the API key and reads as `<key name> (API)`, so an automation never needs a teammate’s credentials."}],"servers":[{"url":"https://api.spike.sh","description":"API server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"Your organisation's API key. Create one in the Spike dashboard under Settings > API. Sent on every request as the `x-api-key` header."}},"schemas":{"IncidentNote":{"type":"object","description":"A note on an incident — what responders write on the incident as they work it.","properties":{"_id":{"type":"string","description":"The note's id. Pin or archive the note by this id."},"content":{"type":["string","null"],"description":"The body of the note, exactly as it was sent. Markdown is stored and returned verbatim — the API never converts or sanitises it, so what renders it decides how it reads. `null` on an archived note, whose body is hidden from everyone but its author."},"isResolution":{"type":"boolean","description":"`true` when the note records what resolved the incident rather than a comment on it."},"archived":{"type":"boolean","description":"`true` when the note has been archived. Archiving is a reversible soft-hide, not a delete: the note stays visible to its author, who can restore it from the dashboard, and everyone else sees an audit line in its place."},"author":{"type":["object","null"],"description":"Who wrote the note, named the way every Spike surface names an actor. A note written through this API carries the API key that wrote it; a note a person wrote in the dashboard, Slack or the mobile app carries that user.","properties":{"type":{"type":"string","enum":["api-key","user"],"description":"Whether an API key or a person wrote the note."},"_id":{"type":"string","description":"The id of the API key or the user."},"name":{"type":"string","description":"How the author reads on an incident. A person's first name; an API key as `<key name> (API)`, for example `Internal key (API)`, so a note no human wrote never reads as though one did. A key with no name reads `Untitled (API)`."}}},"counterId":{"type":"string","description":"The `counterId` of the incident the note belongs to."},"incident":{"type":"string","description":"The `_id` of the incident the note belongs to."},"editedAt":{"type":["string","null"],"description":"When the note was last edited, or `null` if it never was. Only a note's own author may edit one, so a note written by an API key is never edited."},"createdAt":{"type":"string","description":"When the note was written."},"updatedAt":{"type":"string","description":"When the note last changed."}}},"Error":{"type":"object","properties":{"message":{"type":"string","description":"Error message describing the problem"},"error":{"type":"string","description":"Error type or code"},"success":{"type":"boolean","description":"Present on the endpoints whose handlers include it (for example the API-key filter and the public on-call routes). Always `false` on an error."},"valid_api":{"type":"boolean","description":"Present on `401`s produced by the session/API-key filter. `false` means the supplied `x-api-key` was not recognised."},"statusCode":{"type":"number","description":"Echo of the HTTP status, present on a few permission errors."},"status":{"type":"boolean","description":"Present on the status-page component write endpoints, which answer a rejected write `{status: false, error, message}`. Always `false` on an error."}}}}},"paths":{"/incidents/{counterId}/notes/list":{"get":{"operationId":"getIncidentsByCounterIdNotesList","summary":"Read an incident's notes","description":"Read every note on an incident, oldest first, with the pinned one named\nseparately.\n\nAn archived note is included with `archived: true` and `content: null`.\nArchiving hides a note's body from everyone except its author, and an\nAPI key is nobody's author, so this never returns an archived body — the\nsame stub a teammate who did not write it sees.\n\n`pinnedNote` is the `_id` of the note that answers \"where are we right\nnow\", or `null`. One note is pinned at a time.\n\nThe path is `/notes/list` rather than `/notes` because\n`GET /incidents/{counterId}/notes` is the dashboard's own endpoint and\nreturns the dashboard's envelope. It is left alone so nothing already\nreading it changes under them.","tags":["Notes"],"parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"},"description":"Your API key. Find it in your Spike dashboard under Settings > API."},{"name":"counterId","in":"path","required":true,"schema":{"type":"string"},"description":"The incident's `counterId`."}],"responses":{"200":{"description":"The incident's notes.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"incident":{"type":"object","properties":{"_id":{"type":"string"},"counterId":{"type":"string"}}},"pinnedNote":{"type":["string","null"],"description":"The `_id` of the note pinned as the incident's current state, or `null` when nothing is pinned."},"pinnedAt":{"type":["string","null"],"description":"When the pin was last moved, or `null`."},"notes":{"type":"array","items":{"$ref":"#/components/schemas/IncidentNote"}}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No incident with that `counterId` in your organisation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Pin a note as the incident's current state

> Pin a note, so the incident leads with it.\
> \
> The question everyone joining a live incident asks is "where are we right\
> now", and one note at a time holds the answer. Pinning is therefore a\
> move, not a flag: pinning a second note is how you replace the first, and\
> two notes can never both claim to be the current state.\
> \
> Pinning is a decision about the incident rather than about the note, so\
> any note on it can be pinned — including notes your responders wrote.\
> \
> An archived note cannot be pinned (\`409\`): its body is hidden from\
> everyone but its author, so it would read as a blank current state.\
> \
> This endpoint has no body.

```json
{"openapi":"3.1.0","info":{"title":"Spike API","version":"1.0.0"},"tags":[{"name":"Notes","description":"Read and write the notes on an incident with an API key — add a note or a resolution note, pin the one that says where the response is right now, and archive one. A note written this way is attributed to the API key and reads as `<key name> (API)`, so an automation never needs a teammate’s credentials."}],"servers":[{"url":"https://api.spike.sh","description":"API server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"Your organisation's API key. Create one in the Spike dashboard under Settings > API. Sent on every request as the `x-api-key` header."}},"schemas":{"Error":{"type":"object","properties":{"message":{"type":"string","description":"Error message describing the problem"},"error":{"type":"string","description":"Error type or code"},"success":{"type":"boolean","description":"Present on the endpoints whose handlers include it (for example the API-key filter and the public on-call routes). Always `false` on an error."},"valid_api":{"type":"boolean","description":"Present on `401`s produced by the session/API-key filter. `false` means the supplied `x-api-key` was not recognised."},"statusCode":{"type":"number","description":"Echo of the HTTP status, present on a few permission errors."},"status":{"type":"boolean","description":"Present on the status-page component write endpoints, which answer a rejected write `{status: false, error, message}`. Always `false` on an error."}}}}},"paths":{"/incidents/{counterId}/notes/{noteId}/pin":{"put":{"operationId":"putIncidentsByCounterIdNotesByNoteIdPin","summary":"Pin a note as the incident's current state","description":"Pin a note, so the incident leads with it.\n\nThe question everyone joining a live incident asks is \"where are we right\nnow\", and one note at a time holds the answer. Pinning is therefore a\nmove, not a flag: pinning a second note is how you replace the first, and\ntwo notes can never both claim to be the current state.\n\nPinning is a decision about the incident rather than about the note, so\nany note on it can be pinned — including notes your responders wrote.\n\nAn archived note cannot be pinned (`409`): its body is hidden from\neveryone but its author, so it would read as a blank current state.\n\nThis endpoint has no body.","tags":["Notes"],"parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"},"description":"Your API key. Find it in your Spike dashboard under Settings > API."},{"name":"counterId","in":"path","required":true,"schema":{"type":"string"},"description":"The incident's `counterId`."},{"name":"noteId","in":"path","required":true,"schema":{"type":"string"},"description":"The note's `_id`, as returned by `POST /incidents/{counterId}/notes` or `GET /incidents/{counterId}/notes/list`."}],"responses":{"200":{"description":"The note is the incident's pinned note. Re-pinning the note that is already pinned answers the same way and changes nothing.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"pinned":{"type":"boolean"},"pinnedNote":{"type":"string","description":"The `_id` of the note now pinned."}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such incident in your organisation, or no such note on that incident.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The note is archived, so it cannot be pinned.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Clear the incident's pin

> Stop leading the incident with this note. The note itself is untouched —\
> it stays in the timeline where it was written; it just stops being the\
> headline.\
> \
> \`noteId\` is the note you believe holds the pin. If the pin has since\
> moved to a different note, this is refused with a \`409\` rather than\
> clearing whichever note holds it now — the pin moving out from under you\
> is not the same thing as you asking to unpin something else.

```json
{"openapi":"3.1.0","info":{"title":"Spike API","version":"1.0.0"},"tags":[{"name":"Notes","description":"Read and write the notes on an incident with an API key — add a note or a resolution note, pin the one that says where the response is right now, and archive one. A note written this way is attributed to the API key and reads as `<key name> (API)`, so an automation never needs a teammate’s credentials."}],"servers":[{"url":"https://api.spike.sh","description":"API server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"Your organisation's API key. Create one in the Spike dashboard under Settings > API. Sent on every request as the `x-api-key` header."}},"schemas":{"Error":{"type":"object","properties":{"message":{"type":"string","description":"Error message describing the problem"},"error":{"type":"string","description":"Error type or code"},"success":{"type":"boolean","description":"Present on the endpoints whose handlers include it (for example the API-key filter and the public on-call routes). Always `false` on an error."},"valid_api":{"type":"boolean","description":"Present on `401`s produced by the session/API-key filter. `false` means the supplied `x-api-key` was not recognised."},"statusCode":{"type":"number","description":"Echo of the HTTP status, present on a few permission errors."},"status":{"type":"boolean","description":"Present on the status-page component write endpoints, which answer a rejected write `{status: false, error, message}`. Always `false` on an error."}}}}},"paths":{"/incidents/{counterId}/notes/{noteId}/pin":{"delete":{"operationId":"deleteIncidentsByCounterIdNotesByNoteIdPin","summary":"Clear the incident's pin","description":"Stop leading the incident with this note. The note itself is untouched —\nit stays in the timeline where it was written; it just stops being the\nheadline.\n\n`noteId` is the note you believe holds the pin. If the pin has since\nmoved to a different note, this is refused with a `409` rather than\nclearing whichever note holds it now — the pin moving out from under you\nis not the same thing as you asking to unpin something else.","tags":["Notes"],"parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"},"description":"Your API key. Find it in your Spike dashboard under Settings > API."},{"name":"counterId","in":"path","required":true,"schema":{"type":"string"},"description":"The incident's `counterId`."},{"name":"noteId","in":"path","required":true,"schema":{"type":"string"},"description":"The note you believe is pinned."}],"responses":{"200":{"description":"The incident has no pinned note.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"pinned":{"type":"boolean"},"pinnedNote":{"type":"null"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such incident in your organisation.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The pin has moved: the note you named is not the incident's pinned note. Read `pinnedNote` from `GET /incidents/{counterId}/notes/list` to see what is.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```

## Archive a note

> Archive a note on an incident.\
> \
> This is the same reversible soft-hide the dashboard performs, not a\
> delete: the note stays visible to its author, who can restore it from\
> the incident page, and everyone else sees an audit line in its place.\
> Archiving a note that is already archived is harmless.\
> \
> Archiving the incident's pinned note also clears the pin — a pin\
> pointing at a body nobody can read would show the room a blank current\
> state.

```json
{"openapi":"3.1.0","info":{"title":"Spike API","version":"1.0.0"},"tags":[{"name":"Notes","description":"Read and write the notes on an incident with an API key — add a note or a resolution note, pin the one that says where the response is right now, and archive one. A note written this way is attributed to the API key and reads as `<key name> (API)`, so an automation never needs a teammate’s credentials."}],"servers":[{"url":"https://api.spike.sh","description":"API server"}],"security":[{"ApiKeyAuth":[]}],"components":{"securitySchemes":{"ApiKeyAuth":{"type":"apiKey","in":"header","name":"x-api-key","description":"Your organisation's API key. Create one in the Spike dashboard under Settings > API. Sent on every request as the `x-api-key` header."}},"schemas":{"Error":{"type":"object","properties":{"message":{"type":"string","description":"Error message describing the problem"},"error":{"type":"string","description":"Error type or code"},"success":{"type":"boolean","description":"Present on the endpoints whose handlers include it (for example the API-key filter and the public on-call routes). Always `false` on an error."},"valid_api":{"type":"boolean","description":"Present on `401`s produced by the session/API-key filter. `false` means the supplied `x-api-key` was not recognised."},"statusCode":{"type":"number","description":"Echo of the HTTP status, present on a few permission errors."},"status":{"type":"boolean","description":"Present on the status-page component write endpoints, which answer a rejected write `{status: false, error, message}`. Always `false` on an error."}}}}},"paths":{"/incidents/{counterId}/notes/{noteId}":{"delete":{"operationId":"deleteIncidentsByCounterIdNotesByNoteId","summary":"Archive a note","description":"Archive a note on an incident.\n\nThis is the same reversible soft-hide the dashboard performs, not a\ndelete: the note stays visible to its author, who can restore it from\nthe incident page, and everyone else sees an audit line in its place.\nArchiving a note that is already archived is harmless.\n\nArchiving the incident's pinned note also clears the pin — a pin\npointing at a body nobody can read would show the room a blank current\nstate.","tags":["Notes"],"parameters":[{"name":"x-api-key","in":"header","required":true,"schema":{"type":"string"},"description":"Your API key. Find it in your Spike dashboard under Settings > API."},{"name":"counterId","in":"path","required":true,"schema":{"type":"string"},"description":"The incident's `counterId`."},{"name":"noteId","in":"path","required":true,"schema":{"type":"string"},"description":"The note's `_id`."}],"responses":{"200":{"description":"The note was archived.","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean"},"archived":{"type":"boolean"}}}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"No such incident in your organisation, or no such note on that incident.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}}}}}
```
