Skip to main content
Salfio Docs

Search documentation

Type to search this documentation.

Create a note on a client

POST/clients/{clientId}/notesCreate a note on a client

Records a note against the client and returns it as an activity of type: "note". Unlike the generic activity create, the note path attributes the note to a user author (added as a participant contact) and marks the client's AI cards stale so they regenerate.

Author attribution. With a user-scoped key the note is authored by the authenticated user automatically. With a service-scoped key (which carries no user) you MUST supply authorUserId referencing a member of your organization — otherwise the request is rejected with 400 invalid_argument. A cross-organization or unknown authorUserId is likewise 400 invalid_argument.

content is required. participants are people present on the note besides the author; each is linked to (or created as) an org contact by email. occurredAt defaults to now when omitted.

Parameters

clientIdstring · uuidpathrequired

Client UUID.

Request body

required
application/json
objectNoteCreate

Request body for creating a note (`POST /clients/{clientId}/notes`). The note is stored as an activity of type "note". Only `content` is required. `content` is capped at 50,000 characters and `subject` at 500; exceeding either is rejected with `400 invalid_argument` (never a 500).

authorUserIdstring · uuid

User to attribute the note to. Required for service-scoped keys (which carry no user); optional for user-scoped keys, where it defaults to the authenticated user. Must be a member of your organization.

contentstringrequired

The note body (plain text), stored as the note's single message. Up to 50,000 characters; a longer body is rejected with `400 invalid_argument`.

occurredAtstring · date-time

The instant the note refers to. Defaults to now when omitted.

participantsarray of object

People present on the note besides the author; each is linked to (or created as) an org contact by email.

Show child attributes
Show array items
emailstring · emailrequired
namestring

Optional display name for the participant.

subjectnull | string

Optional short subject/title for the note. Up to 500 characters; a longer subject is rejected with `400 invalid_argument`.

maxLength 500

Example request
{
  "authorUserId": "00000000-0000-0000-0000-000000000000",
  "content": "string",
  "occurredAt": "2026-06-09T00:00:00Z",
  "participants": [
    {
      "email": "user@example.com",
      "name": "string"
    }
  ],
  "subject": "string"
}

Responses

201The created note, as an activity of type "note" (content included).application/json

Headers

X-RateLimit-Limit

The request cap for the tighter of the per-organization / per-endpoint windows that applied to this request.

X-RateLimit-Remaining

Requests remaining in the current window.

X-RateLimit-Reset

Unix timestamp (seconds) when the current window resets.

value
allOf · 2 options
Option 1objectEnvelope
datavaluerequired

The response payload — shape depends on the endpoint.

metaobjectrequired

Pagination metadata — populated on list endpoints, empty on single-resource endpoints.

Show child attributes
cursornull | string

Opaque cursor to pass to the next request.

hasMoreboolean | null

True when further pages of results are available.

Option 2object
dataobject

A communication event linked to a client. Projected from Salfio's Conversation + messages + conversation_clients model family. The `clientId` is the "primary" client derived from the junction table — a conversation linked to multiple clients is surfaced once per linked client (from the list endpoints of each). `content` is the full concatenated body of all messages on the conversation, joined by `\n\n---\n\n` — single-resource GETs never truncate it. It is returned only on single-resource GETs; list endpoints omit it for response-size reasons. Webhook delivery payloads cap `content` at 10 KiB (with a `[content truncated at 10 KiB]` marker) — fetch the activity by ID when you need the full text. `immutable` is derived server-side: non-`manual` sources are always immutable on the v1 surface (per the spec source/operation matrix).

Show child attributes
archivedAtnull | string · date-time
clientIdstring · uuidrequired
contentstringrequired

Full concatenated message bodies (single-resource GETs only; capped at 10 KiB in webhook deliveries).

createdAtstring · date-timerequired
idstring · uuidrequired
immutablebooleanrequired

True when the activity's source prevents it from being edited or hard-deleted via the API.

occurredAtstring · date-timerequired
participantsarray of string · emailrequired
Show child attributes
sourcestringrequired

one of "manual", "gmail", "outlook", "fireflies"

subjectnull | string
typestringrequired

one of "email", "meeting", "note", "chat"

updatedAtstring · date-timerequired
Example response
{
  "data": {
    "archivedAt": "2026-06-09T00:00:00Z",
    "clientId": "00000000-0000-0000-0000-000000000000",
    "content": "string",
    "createdAt": "2026-06-09T00:00:00Z",
    "id": "00000000-0000-0000-0000-000000000000",
    "immutable": true,
    "occurredAt": "2026-06-09T00:00:00Z",
    "participants": [
      "user@example.com"
    ],
    "source": "fireflies",
    "subject": "string",
    "type": "chat",
    "updatedAt": "2026-06-09T00:00:00Z"
  },
  "meta": {
    "cursor": "string",
    "hasMore": true
  }
}
400Request body / query parameters failed validation.application/json
objectErrorEnvelope
errorobjectrequired
Show child attributes
codestringrequired

Machine-readable error category.

one of "unauthorized", "forbidden", "not_found", "invalid_argument", "conflict", "rate_limited", "internal_error", "not_implemented"

detailsobject

Optional per-code context (field names, retry windows, …).

messagestringrequired

Human-readable description — intended for operator logs, not end-user display.

Example response
{
  "error": {
    "code": "invalid_argument",
    "message": "limit must be an integer between 1 and 100"
  }
}
401Missing or invalid bearer token. The message is intentionally opaque — do not rely on it to distinguish "missing" from "invalid".application/json
objectErrorEnvelope
errorobjectrequired
Show child attributes
codestringrequired

Machine-readable error category.

one of "unauthorized", "forbidden", "not_found", "invalid_argument", "conflict", "rate_limited", "internal_error", "not_implemented"

detailsobject

Optional per-code context (field names, retry windows, …).

messagestringrequired

Human-readable description — intended for operator logs, not end-user display.

Example response
{
  "error": {
    "code": "unauthorized",
    "message": "Authentication required"
  }
}
404The referenced resource does not exist, or belongs to a different organization than the one owning the API key. The public API does not distinguish between these cases — both return 404 to avoid leaking cross-tenant existence. application/json
objectErrorEnvelope
errorobjectrequired
Show child attributes
codestringrequired

Machine-readable error category.

one of "unauthorized", "forbidden", "not_found", "invalid_argument", "conflict", "rate_limited", "internal_error", "not_implemented"

detailsobject

Optional per-code context (field names, retry windows, …).

messagestringrequired

Human-readable description — intended for operator logs, not end-user display.

Example response
{
  "error": {
    "code": "not_found",
    "message": "client not found"
  }
}
429Per-organization or per-endpoint rate limit exceeded.application/json

Headers

Retry-After

Seconds the client should wait before retrying.

objectErrorEnvelope
errorobjectrequired
Show child attributes
codestringrequired

Machine-readable error category.

one of "unauthorized", "forbidden", "not_found", "invalid_argument", "conflict", "rate_limited", "internal_error", "not_implemented"

detailsobject

Optional per-code context (field names, retry windows, …).

messagestringrequired

Human-readable description — intended for operator logs, not end-user display.

Example response
{
  "error": {
    "code": "rate_limited",
    "details": {
      "retry_after_seconds": 30
    },
    "message": "Rate limit exceeded"
  }
}

Documentation menu