Rest: Pivot's Public API
Overview
The Pivot REST API is public and not used by our client apps. It's purpose is direct integration by customers as well as our own use for building Zapier and Power Automate connectors.
The Rest service is responsible for authentication but not authorization. Rest
API requests require a Bearer token passed via the Authorization header of
each request. This token is an APIKey which is stored in the database and
corresponds to a specific Integration.
Once a Rest route has 1) authenticated the API key as corresponding to an active Integration in the Rest service's own database and 2) determined that the schema of the request body is valid, it uses downstream services for data fetching and mutation.
Rest is written in Go. It's a fairly simple HTPP web server, delegating the complexity of data fetching and mutation to the underlying services it calls with gRPC.
API
Authentication
Note that the current implementation of Integrations is specifically for API Keys and Zapier. It isn't intended (yet) to support third-party apps or OAuth scopes. In the future, those capabilities will possibly be added separately from Rest.
Integration Users and API Keys
The Rest service has an entity Integration and the Facebox service has an
entity User. They share the same id. When an application user wants to
create a new integration, both the Facebox service and the Rest service are
involved. When an application user wants to disable an integration, both the
Facebox service and Rest service must update their respective entities. The
reason for this coupling is to allow the Rest service to own the concepts of API
keys and integrations while allowing Facebox to own the underlying user that
every integration corresponds to.
API keys are very specific to the Rest service - they aren't used by other
services. An API key used in the Authorization header corresponds to an
Integration record in the database which has a 1:1 relationship with a User
entity in the Facebox service.
An 'Integration' created by an organization admin in Pivot is really just a user as far as Facebox, Messenger, and Blockhead are concerned, so permissions for integrations are the same as permissions for users. Downstream data services like Messenger and Blockhead basically don't know what Integration are, the services simply run their normal authorization checks to see if the userId provided by the Rest service has the necessary access for the operation. Integrations are therefore authorized just like any other user -- they can be given Organization Admin roles, room memberships, space memberships, etc.
The Visa service crucially does not allow generation of JWTs for users if
integration_id has a value according to the Facebox service, so they can't be
'logged-in to' and can't be used to authenticate with the Friend service.
/v1 HTTP Routes
The base url is
api.pivot.app/v1and all requests must include an Authorization header with valuebearer [apiKey].
/users
- Get user
GET /users/:id
/spaces
- Get all spaces
GET /spaces - Get a space
GET /spaces/:id - Create a space
POST /spaces - Update a space
PATCH /spaces/:id
/members
- Get all members for a space
GET /spaces/:id/members - Get a space member
GET /spaces/:id/members/:id - Create a space member
POST /spaces/:id/membersMust already know the user id. If you know the email but not the user id, create an invite instead.
- Update a space member
PATCH /spaces/:id/members/:id
/invites
- Get all invites
GET /spaces/:id/invites - Get existing invite
GET /spaces/:id/invites/:id - Update existing invite
PATCH /spaces/:id/invites/:id - Create invite
POST /spaces/:id/invites
/blocks
The Block entity is used generically for all GET operations, however different
block types have their own POST and PATCH operations which return blocks.
GET /blocks/:idGET /blocks?spaceId?=:id&parentId=:id- Either spaceId or parentId is required and the other must be undefined. This operation will not return all blocks the user has access to, only those for a given spaceId (with no parent) or a given parent blockId.
/database-items
POST /blocks/database-itemsPATCH /blocks/database-items/:id
/page
POST /blocks/pages
Entities
- User
- Invite
- Space Member
- Space
- Block
NATS
// TODO: Clarify if webhooks are part of Rest and if so, leverage NATS.
Database
Rest uses Amazon Keyspaces (managed Cassandra) for its data storage needs.
- Integration - an integration is an identity that the Rest service can be
accessed via. It corresponds to a
user_idin Facebox, which Rest can then pass to downstream services, so that those services an run their normal Authz checks on RPCs from Rest.
Deployment
Temporal Workflows
N/A
Security
- Rate limiting at the firewall level.