BetaPointPerson is still in beta — expect some rough edges.
Developers

PointPerson API v1

An organization's own systems read and write its events with a key its admins make. A key acts as the organization, never as a person: every write is made for a roster member and held to the organization's rules as theirs. Refusals are { error, reason }, and reason codes are part of the contract.

Signing in

An admin makes a key on the organization's Integrations tab, with the scopes it needs. It is shown once.

Authorization: Bearer pp_live_…

An organization's API key, made by its admins. Pass as Authorization: Bearer pp_live_…; /api/v1 only.

Within v1 an answer may gain fields and a request may gain optional ones; nothing is renamed, removed or made required. A refusal is { error, reason }: branch on reason.

Scopes

events:readRead events3 routes
events:writeMake, edit and cancel events3 routes
roster:readRead members and teams2 routes
roster:writeChange members and teams8 routes
rules:readRead templates, fields and rules3 routes
rules:writeDraft rules and import packs3 routes
rules:publishPublish rules1 route

Events

GET/api/v1/events

A page of the events the organization governs (made from its templates or linked to its groups), by id

Needs events:read

Parameters

fromquery · stringRFC 3339: events that end at or after it (a series always)
toquery · stringRFC 3339: events that start before it
templatequery · stringA template's id
groupquery · integerA group's id
updated_sincequery · stringRFC 3339: events whose history has a line since
cursorquery · stringnext_cursor of the page before
limitquery · integer1 to 100, 50 when absent

Answers

  • 200 Events · object
  • 400 invalid_query, with param
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

POST/api/v1/events

Make an event for a roster member, held to the organization's rules as theirs; counts toward the daily run cap

Needs events:write

Parameters

Idempotency-Keyheader · stringThe same key and body within 24 hours answers the first answer (Idempotent-Replayed: true); another body is 409 idempotency_conflict, and while the first runs, 409 idempotency_in_progress

Body

As POST /events takes it, without overrides. Fields not listed are taken too.
on_behalf_of
required
string (uuid)The public id of a current roster member: they are the event's creator, its rules judge it by their teams, and they are told the key made it
template_idstring (uuid)One of the organization's templates; this or group_ids (groups of the organization's the member may share with) is required

Answers

  • 201 Event · ApiEvent
  • 202 Event, held for approval: without the held opt-in, only its id and approval · ApiEvent
  • 400 on_behalf_of_required, on_behalf_of_not_member, overrides_not_allowed, invalid_template (a template not the organization's), invalid_group_ids (a group not one of its live groups), unsupported_field (with field: dates, poll, slots, details_pending, template_from_event_id, replaces, series_tag_id, series_group_id, audit_stream_id, extraction_id), and every refusal POST /events answers
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 409 idempotency_conflict, idempotency_in_progress
  • 422 rule_violation, as POST /events
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

GET/api/v1/events/{id}

One event the organization governs

Needs events:read

Parameters

id
required
path · integer

Answers

  • 200 Event · ApiEvent
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 404 event_not_found (also an event held for approval, without the held opt-in)
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

PATCH/api/v1/events/{id}

Change the fields named and leave the rest, written as the creator's edit and held to the rules as any edit

Needs events:write

Parameters

id
required
path · integer

Body

Any field PUT /events/{id} takes, without overrides. Fields not listed are taken too.

Answers

  • 200 Event · ApiEvent
  • 202 Event, the change held for approval · ApiEvent
  • 400 overrides_not_allowed, invalid_template, invalid_group_ids, and every refusal PUT /events/{id} answers
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 404 event_not_found
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

POST/api/v1/events/describe

What the create screen holds for on_behalf_of, as POST /events/describe answers it

Needs events:read

Body

on_behalf_of
required
string (uuid)The public id of a current roster member: they are the event's creator, its rules judge it by their teams, and they are told the key made it

Answers

  • 200 As POST /events/describe
  • 400 on_behalf_of_required, on_behalf_of_not_member, overrides_not_allowed, invalid_template (a template not the organization's), invalid_group_ids (a group not one of its live groups), unsupported_field (with field: dates, poll, slots, details_pending, template_from_event_id, replaces, series_tag_id, series_group_id, audit_stream_id, extraction_id), and every refusal POST /events answers
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

POST/api/v1/events/{id}/cancel

Cancel an event, as its creator would

Needs events:write

Parameters

id
required
path · integer
Idempotency-Keyheader · stringThe same key and body within 24 hours answers the first answer (Idempotent-Replayed: true); another body is 409 idempotency_conflict, and while the first runs, 409 idempotency_in_progress

Answers

  • 200 Event · ApiEvent
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 404 event_not_found
  • 409 already_cancelled
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

Members and teams

GET/api/v1/members

The roster, as GET /organizations/{id}/members

Needs roster:read

Answers

  • 200 As GET /organizations/{id}/members
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

POST/api/v1/members

Add an address to the roster, or invite it to a community organization, as POST /organizations/{id}/members

Needs roster:write

Parameters

Idempotency-Keyheader · stringThe same key and body within 24 hours answers the first answer (Idempotent-Replayed: true); another body is 409 idempotency_conflict, and while the first runs, 409 idempotency_in_progress

Answers

  • 201 As POST /organizations/{id}/members
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

PUT/api/v1/members/{publicId}

Set a member's role, as PATCH /organizations/{id}/members/{publicId}

Needs roster:write

Parameters

publicId
required
path · string

Answers

  • 200 As PATCH /organizations/{id}/members/{publicId}
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

DELETE/api/v1/members/{publicId}

Take a member off the roster

Needs roster:write

Parameters

publicId
required
path · string

Answers

  • 204 Removed
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

GET/api/v1/teams

The teams, as GET /organizations/{id}/teams

Needs roster:read

Answers

  • 200 As GET /organizations/{id}/teams
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

POST/api/v1/teams

Make a team

Needs roster:write

Parameters

Idempotency-Keyheader · stringThe same key and body within 24 hours answers the first answer (Idempotent-Replayed: true); another body is 409 idempotency_conflict, and while the first runs, 409 idempotency_in_progress

Answers

  • 201 As POST /organizations/{id}/teams
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

PATCH/api/v1/teams/{id}

Rename a team

Needs roster:write

Parameters

id
required
path · string

Answers

  • 200 As PATCH /organizations/{id}/teams/{teamId}
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

DELETE/api/v1/teams/{id}

Delete a team

Needs roster:write

Parameters

id
required
path · string

Answers

  • 200 As DELETE /organizations/{id}/teams/{teamId}
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

PUT/api/v1/teams/{id}/members/{publicId}

Put a member on a team

Needs roster:write

Parameters

id
required
path · string
publicId
required
path · string

Answers

  • 204 On the team
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

DELETE/api/v1/teams/{id}/members/{publicId}

Take a member off a team

Needs roster:write

Parameters

id
required
path · string
publicId
required
path · string

Answers

  • 204 Off the team
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

Templates, fields, rules and packs

GET/api/v1/templates

The organization's templates, as GET /event-templates serves each

Needs rules:read

Answers

  • 200 Templates · array of EventTemplate
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

GET/api/v1/fields

The organization's custom fields

Needs rules:read

Answers

  • 200 As GET /organizations/{id}/fields
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

GET/api/v1/rules

The organization's rules, drafts and published

Needs rules:read

Answers

  • 200 As GET /organizations/{id}/rules
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

POST/api/v1/rules/publish

Publish every draft, as POST /organizations/{id}/rules/publish; read the dry-run first

Needs rules:publish

Parameters

Idempotency-Keyheader · stringThe same key and body within 24 hours answers the first answer (Idempotent-Replayed: true); another body is 409 idempotency_conflict, and while the first runs, 409 idempotency_in_progress

Answers

  • 200 As POST /organizations/{id}/rules/publish
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

GET/api/v1/packs/export

Export a pack of the templates and rules named, saving nothing: the pack named at the version it has, or a new one at version 1

Needs rules:write

Parameters

name
required
query · string
templatequery · stringA template's id; repeat for more
rulequery · stringA rule's id; repeat for more
packquery · stringThe uid of a pack to export the next version of

Answers

  • 200 Pack · Pack
  • 400 name_required, pack_empty
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 404 pack_item_not_found
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

POST/api/v1/packs/import/preview

What importing a pack would do

Needs rules:write

Parameters

Idempotency-Keyheader · stringThe same key and body within 24 hours answers the first answer (Idempotent-Replayed: true); another body is 409 idempotency_conflict, and while the first runs, 409 idempotency_in_progress

Body

pack
required
Pack
mappingobjectBy uid: one of the organization's own team, group or endpoint ids, "new" for a new team, or null for nothing. Unmapped, each maps to what an earlier import made, else the one with its name, else (a team) a new one
keeparray of string (uuid)For a newer version, the items whose changes are written; all when absent

Answers

  • 200 Plan · PackPlan
  • 400 pack_invalid (with path, the place in the document), pack_mapping_required (with uids), and any refusal an item's own write answers, with the path to the item: too_many_fields, team_name_taken, invalid_field_value, constraint_invalid…
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

POST/api/v1/packs/import

Import a pack as drafts

Needs rules:write

Parameters

Idempotency-Keyheader · stringThe same key and body within 24 hours answers the first answer (Idempotent-Replayed: true); another body is 409 idempotency_conflict, and while the first runs, 409 idempotency_in_progress

Body

pack
required
Pack
mappingobjectBy uid: one of the organization's own team, group or endpoint ids, "new" for a new team, or null for nothing. Unmapped, each maps to what an earlier import made, else the one with its name, else (a team) a new one
keeparray of string (uuid)For a newer version, the items whose changes are written; all when absent

Answers

  • 201 Plan · PackPlan
  • 400 pack_invalid (with path, the place in the document), pack_mapping_required (with uids), and any refusal an item's own write answers, with the path to the item: too_many_fields, team_name_taken, invalid_field_value, constraint_invalid…
  • 401 key_required (no key, or a session's token), invalid_key (revoked, expired or none)
  • 402 entitlement_limit_reached: the plan that pays for the organization lapsed
  • 403 scope_missing, with scope: the scope the route needs
  • 429 rate_limited (10 a second, bursts of 50) or daily_cap (100,000 requests a day; an event write past the organization's 10,000 runs a day); Retry-After says when

Schemas

LocationInput

idinteger
namestring
addressstring
latitudenumber
longitudenumber
place_idstring
providerstring

EventTemplate

idstring (uuid)
slugstring
namestring
colorstring
category_keysarray of string
descriptionstring, or null
sort_orderinteger
created_by_public_idstring (uuid), or null
group_idinteger, or null
organization_idstring (uuid), or nullThe organization that owns the template; such a template has no created_by_public_id
contactContactAn organization's template's: whom to ask about its own constraints. Null for any other
override_teamsarray of string (uuid)An organization's template's: the teams that may override its own constraints (its admins always may)
custom_fieldsarray of OrganizationFieldAn organization's template's: the live fields of its organization, in its order, each of which `fields` carries a `custom.<field id>` pair for — display shown or hidden (hidden with no default until an admin shows or fixes it), a default in the kind's shape, and the constraints the kind takes. Empty for any other template.
wizard_preset_idstring, or null
workflowstring
favoriteboolean
updated_atstring (date-time)
fieldsobject
subtask_defaultsobject, or null
subtask_nounSubtaskNoun
claim_labelstring, or nullRenames the whole-event claim call to action ("I'm in charge of soccer practice"). Null keeps the built-in wording.
poll_optionsinteger, or null
find_time_windowstring, or null
series_dates_countinteger, or null

TemplateField

display
required
one of shown, hidden, locked
value
required
object, or null
requiredbooleanevent.location, event.notes, and a custom field of any kind but yes_no: the creator must give one
optionsarray of LocationInput or string (uuid)event.location and a custom location field: the only venues it may be, matched by place_id when the venue has one, else by name and address. A custom choice field: the only choice ids it may be, a subset of its live choices
minnumberevent.capacity, event.max_party_size (people), event.duration (minutes): whole numbers. A custom number field: a decimal
maxnumberevent.capacity, event.max_party_size (people), event.duration (minutes): whole numbers. On capacity and party size, no limit breaks a max. A custom number field: a decimal
notice_hoursintegerevent.start_time: how far ahead of now an event may start
weekdaysarray of integerevent.start_time: the ISO weekdays (Monday = 1) an event may start on, a timed start read on the event's own timezone
earliest_startstring (date-time)Served beside notice_hours: the earliest timed start it allows as of the read, to the minute
earliest_datestring (date-time)Served beside notice_hours: the earliest all-day date it allows as of the read, with the server's day of grace
repeatsarray of one of weekly, monthly_weekdayServed beside weekdays that leave a day out: the only repeats that cannot land on one (weekly on allowed days, monthly on the nth of one)

SubtaskNoun

singularstring
pluralstring

OrganizationField

idstring (uuid)
labelstring
kindone of text, number, yes_no, choice, date, person, location
multilinebooleantext
unitstring, or nullnumber
multiplebooleanchoice: several may be picked
helpstring, or null
visibilityone of everyone, organizationWho reads the value on an event: anyone who may read the event, or the organization's roster and anyone who may update the event
choicesarray of OrganizationFieldChoicechoice: the live choices, in order

OrganizationFieldChoice

idstring (uuid)
labelstring

ApiEvent

idinteger
urlstring
sequenceinteger
titlestring
cancelledboolean
all_dayboolean
startstring (date-time)A timed event's; an all-day event has date instead
endstring (date-time)
datestring (date)An all-day event's floating date, never an instant
timezonestring, or null
repeatsstring, or nullRFC 5545 RRULE
occurrencestring, or null
locationobject, or null
notesstring, or null
templateobject, or null
groupsarray of object
custom_fieldsarray of object
approvalone of pending, declined, lapsed, or nullWith the held opt-in: null for an event going ahead
updated_atstring (date-time), or nullWhen the event's history last had a line
hostsarray of objectWith the hosts opt-in
attendeesarray of objectWith the attendees opt-in

Pack

format
required
one of pointperson.pack
format_version
required
one of 1
uid
required
string (uuid)The pack's, kept across exports
version
required
integer
name
required
string
descriptionstring, or null
exported_fromobject
teamsarray of object
groupsarray of object
webhooksarray of object
fieldsarray of object
templatesarray of objectEach a uid and the body POST /event-templates takes, every id a uid: token
rulesarray of objectEach a uid and the body POST /organizations/{id}/rules takes, every id a uid: token

PackPlan

packobject
teamsarray of object
groupsarray of object
webhooksarray of object
fieldsarray of object
templatesarray of object
rulesarray of object
mapping_requiredarray of string (uuid)Teams and groups a condition or an approval names that map to nothing

Contact

userobject
teamobject
adminsboolean
notestring

Error

errorstring
reasonstring