Skip to main content

Feathr API (0.0.0)

Download OpenAPI specification:Download

Standalone FastAPI public API on crane.

breadcrumbs

List Breadcrumbs

List breadcrumbs for the caller's account. Requires breadcrumbs:read.

Optional filters combine with AND: flavor, person_id, campaign_id, and a since/until activity-time range. Public filter names map to the internal Elasticsearch fields (flvr/per_id/cpn_id/d_c). Results are ordered newest activity first.

Authorizations:
HTTPBearer
query Parameters
BreadcrumbFlavors (string) or Flavor (null) (Flavor)

Filter by activity flavor.

Person Id (string) or Person Id (null) (Person Id)

Filter by person id.

Campaign Id (string) or Campaign Id (null) (Campaign Id)

Filter by campaign id.

Project Id (string) or Project Id (null) (Project Id)

Filter by project id.

Since (string) or Since (null) (Since)

Min activity time.

Until (string) or Until (null) (Until)

Max activity time.

page
integer (Page) >= 1
Default: 1

1-based page number.

size
integer (Size) [ 1 .. 100 ]
Default: 25

Items per page (max 100).

Responses

Response samples

Content type
application/json
{
  • "items": [
    ],
  • "page": 0,
  • "size": 0,
  • "total": 0
}

Append Breadcrumb

Append a breadcrumb (activity record). Requires breadcrumbs:write.

The crumb's person is resolved-or-created inline from its identifiers, so no separate person-first step is needed. Breadcrumbs are append-only; supplying an Idempotency-Key makes the write deterministic (the key is hashed into the document's id), so re-delivery overwrites the same record rather than duplicating it.

Authorizations:
HTTPBearer
header Parameters
Idempotency-Key (string) or Idempotency-Key (null) (Idempotency-Key)
Request Body schema: application/json
required
Campaign Id (string) or Campaign Id (null) (Campaign Id)
Email (string) or Email (null) (Email)
External Id (string) or External Id (null) (External Id)
F Id (string) or F Id (null) (F Id)
flavor
required
string (BreadcrumbFlavors)
Enum: "ad_click" "ad_view" "blocked" "bot_partner_message_link_click" "bot_partner_message_unsubscribe" "bot_partner_message_view" "bot_pinpoint_tracked_email_click" "bot_pinpoint_tracked_email_open" "bot_pinpoint_tracked_email_unsubscribe" "contact_list_import" "conversation_response" "convert" "created_by_import" "custom" "dashboard_create" "dashboard_import" "dashboard_link_click" "dashboard_send_complete" "dashboard_send_request" "dashboard_submit" "dashboard_view" "deduplicated" "donation" "email_bot_detection_click" "email_link_click" "email_preferences_resubscribe" "email_preferences_update" "email_not_sent_via_opt_out" "email_send" "email_view" "form_submission" "form_view" "imis_create" "imis_update" "page_link_click" "page_view" "partner_message_complaint" "partner_message_delivered" "partner_message_hardbounce" "partner_message_link_click" "partner_message_rendering_failure" "partner_message_send" "partner_message_softbounce" "partner_message_suppression" "partner_message_unsubscribe" "partner_message_view" "pinpoint_tracked_email_click" "pinpoint_tracked_email_complaint" "pinpoint_tracked_email_delivered" "pinpoint_tracked_email_hardbounce" "pinpoint_tracked_email_open" "pinpoint_tracked_email_rendering_failure" "pinpoint_tracked_email_send" "pinpoint_tracked_email_softbounce" "pinpoint_tracked_email_suppression" "pinpoint_tracked_email_unsubscribe" "raisers_edge_constituent_created" "raisers_edge_constituent_updated" "raisers_edge_constituent_summary" "raisers_edge_gift_added" "report_link_click" "report_view" "shared_email_preferences_update" "update" "user_create" "user_update" "updated_by_import" "zapier_import" "zapier_update"
Occurred At (string) or Occurred At (null) (Occurred At)
Person Id (string) or Person Id (null) (Person Id)
Project Id (string) or Project Id (null) (Project Id)

Responses

Request samples

Content type
application/json
{
  • "campaign_id": "string",
  • "email": "string",
  • "external_id": "string",
  • "f_id": "string",
  • "flavor": "ad_click",
  • "occurred_at": "2019-08-24T14:15:22Z",
  • "person_id": "string",
  • "project_id": "string"
}

Response samples

Content type
application/json
{
  • "campaign_id": "string",
  • "created_at": "2019-08-24T14:15:22Z",
  • "email": "string",
  • "flavor": "string",
  • "id": "string",
  • "person_id": "string",
  • "project_id": "string"
}

campaigns

List Campaigns

List the account's campaigns. Requires campaigns:read.

Authorizations:
HTTPBearer
query Parameters
page
integer (Page) >= 1
Default: 1

1-based page number.

size
integer (Size) [ 1 .. 100 ]
Default: 25

Items per page (max 100).

Responses

Response samples

Content type
application/json
{
  • "items": [
    ],
  • "page": 0,
  • "size": 0,
  • "total": 0
}

Get Campaign

Fetch one campaign by id, own account only. Requires campaigns:read.

Authorizations:
HTTPBearer
path Parameters
campaign_id
required
string (Campaign Id)

Responses

Response samples

Content type
application/json
{
  • "date_created": "2019-08-24T14:15:22Z",
  • "date_end": "2019-08-24T14:15:22Z",
  • "date_start": "2019-08-24T14:15:22Z",
  • "description": "string",
  • "id": "string",
  • "is_enabled": true,
  • "kind": "string",
  • "name": "string",
  • "project_id": "string",
  • "state": "string"
}

custom-fields

List Custom Fields

List the account's custom fields. Requires custom_fields:read.

Authorizations:
HTTPBearer
query Parameters
Collection (string) or Collection (null) (Collection)

Filter to fields for one entity type.

page
integer (Page) >= 1
Default: 1

1-based page number.

size
integer (Size) [ 1 .. 100 ]
Default: 25

Items per page (max 100).

Responses

Response samples

Content type
application/json
{
  • "items": [
    ],
  • "page": 0,
  • "size": 0,
  • "total": 0
}

Create Custom Field

Create a custom field for the caller's account. Requires custom_fields:write.

Allocates the storage key, creates the Elasticsearch mapping so values can be indexed, then persists the definition. The owning account comes from the API key; key+collection must be unique (409) and the account-wide field limit is enforced (422).

Authorizations:
HTTPBearer
Request Body schema: application/json
required
collection
required
string (Collection)
Enum: "Person" "Breadcrumb" "Partner"
data_type
required
string (Data Type)
Enum: "str" "int" "float" "bool" "list" "date" "money" "unicode"
Description (string) or Description (null) (Description)
form_type
string (Form Type)
Default: "text"
Enum: "text" "number" "textarea" "email" "url" "image"
key
required
string (Key) [ 1 .. 255 ] characters
Label (string) or Label (null) (Label)

Responses

Request samples

Content type
application/json
{
  • "collection": "Person",
  • "data_type": "str",
  • "description": "string",
  • "form_type": "text",
  • "key": "string",
  • "label": "string"
}

Response samples

Content type
application/json
{
  • "collection": "Person",
  • "data_type": "str",
  • "description": "string",
  • "form_type": "text",
  • "id": "string",
  • "is_default": true,
  • "is_read_only": true,
  • "key": "string",
  • "label": "string"
}

Delete Custom Field

Archive a custom field (soft delete). Requires custom_fields:write.

Soft delete preserves already-stored values and the Elasticsearch mapping (mappings are only reclaimed on reindex). Integration-managed (read-only) fields cannot be deleted via the API (403).

Authorizations:
HTTPBearer
path Parameters
field_id
required
string (Field Id)

Responses

Response samples

Content type
{
  • "detail": "string",
  • "status": 0,
  • "title": "string",
  • "type": "about:blank"
}

Get Custom Field

Fetch one custom field by id, own account only. Requires custom_fields:read.

Authorizations:
HTTPBearer
path Parameters
field_id
required
string (Field Id)

Responses

Response samples

Content type
application/json
{
  • "collection": "Person",
  • "data_type": "str",
  • "description": "string",
  • "form_type": "text",
  • "id": "string",
  • "is_default": true,
  • "is_read_only": true,
  • "key": "string",
  • "label": "string"
}

Update Custom Field

Update a custom field's display attributes. Requires custom_fields:write.

Integration-managed (read-only) fields cannot be edited via the API (403).

Authorizations:
HTTPBearer
path Parameters
field_id
required
string (Field Id)
Request Body schema: application/json
required
Description (string) or Description (null) (Description)
Form Type (string) or Form Type (null) (Form Type)
Label (string) or Label (null) (Label)

Responses

Request samples

Content type
application/json
{
  • "description": "string",
  • "form_type": "text",
  • "label": "string"
}

Response samples

Content type
application/json
{
  • "collection": "Person",
  • "data_type": "str",
  • "description": "string",
  • "form_type": "text",
  • "id": "string",
  • "is_default": true,
  • "is_read_only": true,
  • "key": "string",
  • "label": "string"
}

me

Whoami

Introspect the calling API key: its account, scopes, metadata, and limits.

Requires only a valid key (any scope) and does not count against the key's rate limit. Metadata is read fresh from storage by the key's id; rate-limit counters reflect the bucket as of this request.

Authorizations:
HTTPBearer

Responses

Response samples

Content type
application/json
{
  • "account_id": "string",
  • "expires_at": "2019-08-24T14:15:22Z",
  • "key_id": "string",
  • "last_four": "string",
  • "last_used_at": "2019-08-24T14:15:22Z",
  • "prefix": "string",
  • "rate_limit": {
    },
  • "revoked": false,
  • "scopes": [
    ],
  • "service_name": "string"
}

persons

List Persons

List persons last seen since updated_since. Requires persons:read.

updated_since maps to the person's last-seen time and is capped at 30 days ago for performance (older values are rejected). Optional filters: external_id (exact match) and tag_ids (repeatable; AND — the person must hold every listed tag). Inner breadcrumbs are always excluded; results are ordered by last-seen ascending for stable paging. Custom-field values are translated to public keys.

Authorizations:
HTTPBearer
query Parameters
updated_since
required
string <date-time> (Updated Since)

Return persons last seen at/after this time (max 30 days ago).

External Id (string) or External Id (null) (External Id)

Filter to the person with this exact external id.

Array of Tag Ids (strings) or Tag Ids (null) (Tag Ids)

Filter to persons holding ALL of these tag ids (AND).

page
integer (Page) >= 1
Default: 1

1-based page number.

size
integer (Size) [ 1 .. 100 ]
Default: 25

Items per page (max 100).

Responses

Response samples

Content type
application/json
{
  • "items": [
    ],
  • "page": 0,
  • "size": 0,
  • "total": 0
}

Upsert Person

Upsert a person, matched by stable key. Requires persons:write.

Matches an existing person by external_id → email → f_id (or creates one), then applies the provided attributes. A stable external_id makes this idempotent — re-delivery matches the same person rather than duplicating it.

Authorizations:
HTTPBearer
Request Body schema: application/json
required
Email (string) or Email (null) (Email)
External Id (string) or External Id (null) (External Id)
F Id (string) or F Id (null) (F Id)
First Name (string) or First Name (null) (First Name)
Last Name (string) or Last Name (null) (Last Name)
Phone (string) or Phone (null) (Phone)

Responses

Request samples

Content type
application/json
{
  • "email": "string",
  • "external_id": "string",
  • "f_id": "string",
  • "first_name": "string",
  • "last_name": "string",
  • "phone": "string"
}

Response samples

Content type
application/json
{
  • "custom_fields": { },
  • "date_created": "2019-08-24T14:15:22Z",
  • "date_last_seen": "2019-08-24T14:15:22Z",
  • "email": "string",
  • "external_id": "string",
  • "first_name": "string",
  • "id": "string",
  • "last_name": "string",
  • "phone": "string",
  • "tag_ids": [
    ]
}

Get Person

Fetch a person by id, scoped to the caller's account. Requires persons:read.

Inner breadcrumbs are always excluded from the fetch (they are large and served by the breadcrumbs endpoint). Custom-field values are translated to public keys.

Authorizations:
HTTPBearer
path Parameters
person_id
required
string (Person Id)

Responses

Response samples

Content type
application/json
{
  • "custom_fields": { },
  • "date_created": "2019-08-24T14:15:22Z",
  • "date_last_seen": "2019-08-24T14:15:22Z",
  • "email": "string",
  • "external_id": "string",
  • "first_name": "string",
  • "id": "string",
  • "last_name": "string",
  • "phone": "string",
  • "tag_ids": [
    ]
}

Update Person

Update a person's attributes by id, own account only. Requires persons:write.

Authorizations:
HTTPBearer
path Parameters
person_id
required
string (Person Id)
Request Body schema: application/json
required
Email (string) or Email (null) (Email)
First Name (string) or First Name (null) (First Name)
Last Name (string) or Last Name (null) (Last Name)
Phone (string) or Phone (null) (Phone)

Responses

Request samples

Content type
application/json
{
  • "email": "string",
  • "first_name": "string",
  • "last_name": "string",
  • "phone": "string"
}

Response samples

Content type
application/json
{
  • "custom_fields": { },
  • "date_created": "2019-08-24T14:15:22Z",
  • "date_last_seen": "2019-08-24T14:15:22Z",
  • "email": "string",
  • "external_id": "string",
  • "first_name": "string",
  • "id": "string",
  • "last_name": "string",
  • "phone": "string",
  • "tag_ids": [
    ]
}

Add Person Tags

Add tags to a person. Requires persons:write.

Idempotent — tags already on the person are left unchanged, no duplicates are created. View a person's tags via GET /persons/{id} (tag_ids) and filter by them on GET /persons.

Authorizations:
HTTPBearer
path Parameters
person_id
required
string (Person Id)
Request Body schema: application/json
required
tag_ids
required
Array of strings (Tag Ids) non-empty

Responses

Request samples

Content type
application/json
{
  • "tag_ids": [
    ]
}

Response samples

Content type
{
  • "detail": "string",
  • "status": 0,
  • "title": "string",
  • "type": "about:blank"
}

Remove Person Tag

Remove a tag from a person. Requires persons:write. A no-op if the person doesn't hold the tag.

Authorizations:
HTTPBearer
path Parameters
person_id
required
string (Person Id)
tag_id
required
string (Tag Id)

Responses

Response samples

Content type
{
  • "detail": "string",
  • "status": 0,
  • "title": "string",
  • "type": "about:blank"
}

projects

List Projects

List the account's projects. Requires projects:read.

Authorizations:
HTTPBearer
query Parameters
page
integer (Page) >= 1
Default: 1

1-based page number.

size
integer (Size) [ 1 .. 100 ]
Default: 25

Items per page (max 100).

Responses

Response samples

Content type
application/json
{
  • "items": [
    ],
  • "page": 0,
  • "size": 0,
  • "total": 0
}

Get Project

Fetch one project by id, own account only. Requires projects:read.

Authorizations:
HTTPBearer
path Parameters
project_id
required
string (Project Id)

Responses

Response samples

Content type
application/json
{
  • "date_created": "2019-08-24T14:15:22Z",
  • "date_end": "2019-08-24T14:15:22Z",
  • "date_start": "2019-08-24T14:15:22Z",
  • "id": "string",
  • "location": "string",
  • "name": "string",
  • "registration_url": "string",
  • "site_url": "string"
}

tags

List Tags

List the account's tags, optionally filtered by context. Requires tags:read.

Authorizations:
HTTPBearer
query Parameters
Context (string) or Context (null) (Context)
page
integer (Page) >= 1
Default: 1

1-based page number.

size
integer (Size) [ 1 .. 100 ]
Default: 25

Items per page (max 100).

Responses

Response samples

Content type
application/json
{
  • "items": [
    ],
  • "page": 0,
  • "size": 0,
  • "total": 0
}

Create Tag

Create a tag for the caller's account. Requires tags:write.

The account (parent) is taken from the API key, never the request body. A duplicate (name, context) against a live tag is a 409; if it collides with a soft-deleted (archived) tag, that tag is revived and returned — matching the in-app get-or-create so a deleted name isn't locked out forever.

Authorizations:
HTTPBearer
Request Body schema: application/json
required
context
required
string (Context)
Enum: "event" "account" "person_segment" "partner" "breadcrumb" "person"
name
required
string (Name) [ 1 .. 64 ] characters

Responses

Request samples

Content type
application/json
{
  • "context": "event",
  • "name": "string"
}

Response samples

Content type
application/json
{
  • "context": "string",
  • "date_created": "2019-08-24T14:15:22Z",
  • "id": "string",
  • "name": "string"
}

Delete Tag

Archive a tag (soft delete; preserves references). Requires tags:write.

Authorizations:
HTTPBearer
path Parameters
tag_id
required
string (Tag Id)

Responses

Response samples

Content type
{
  • "detail": "string",
  • "status": 0,
  • "title": "string",
  • "type": "about:blank"
}

Get Tag

Fetch one tag by id, own account only. Requires tags:read.

Authorizations:
HTTPBearer
path Parameters
tag_id
required
string (Tag Id)

Responses

Response samples

Content type
application/json
{
  • "context": "string",
  • "date_created": "2019-08-24T14:15:22Z",
  • "id": "string",
  • "name": "string"
}

Update Tag

Update a tag's name and/or context, own account only. Requires tags:write.

Authorizations:
HTTPBearer
path Parameters
tag_id
required
string (Tag Id)
Request Body schema: application/json
required
Context (string) or Context (null) (Context)
Name (string) or Name (null) (Name)

Responses

Request samples

Content type
application/json
{
  • "context": "event",
  • "name": "string"
}

Response samples

Content type
application/json
{
  • "context": "string",
  • "date_created": "2019-08-24T14:15:22Z",
  • "id": "string",
  • "name": "string"
}