about

docs

pricing

oss

consulting

Appearance

Rest API & Webhooks


Page:
/development


Overview

The floro rest API and webhooks are designed to allow you to consume updates from floro and integrate floro into any service you like. At this time, the floro API is read-only. All state mutations occur offline and are pushed or merged by the users of the repository.

Floro offers both online and offline versions of the rest API & webhooks. This means you do not need to use tools like ngrok or local tunnels to test your floro integration, you can test your integration with your local repository.

Currently there is only one floro webhook. The webhook emits a single event, which is when a branch is updated. You can use this webhook to know when to pull changes from a floro branch.

API Hostnames

Local: http://127.0.0.1:63403
Remote: https://api.floro.io



Setting up API Keys

You control API access to repositories by enabling a given api key or webhook token for that repository.

Setting up API keys is easy. All offline API Keys and Webhook tokens are created by opening up the Developer Settings page from your personal dashboard. Remote Api Keys can be created from either your personal dashboard or your organization dashboard, where you create them depends on the type of repository. If your repository is a personal repository, click on the Developer Settings tab from your personal dashboard. If the repository belongs to an organization, click on the Developer Settings tab from the organization's dashboard.

Locale API Keys & Webhook Tokens

From your local repository, click on local settings (you need to be in preview mode).



You will now be able to enable your local api keys to test your integration locally.

Remote API Keys & Webhook Tokens

From your remote repository, click on remote settings (you will need to have this permission enabled).



Next click on the Configure API Settings tab in the upper right corner of the Repo Settings page.



You can now enable the api keys you want to give remote access to the repository and create the corresponding webhooks.

Third Party Access

Floro does not have any OAuth flow for offering third-party access. The safest and easiest integration is for you to create an API key that you provide to a third party. You can then manage access to the repositories associated to that key through floro.


Rest API



All API requests are GET requests. All responses are of content type application/json. All API requests must include the floro-api-key header, in which you should pass an enabled header (no bearer prefix required).


Healthcheck Endpoint (Remote Only)


You may monitor the floro API yourself. The healthcheck only exists for remote requests. You must include the floro-api-key header in your healthcheck. A 403 response codes indicates an invalid API key. A 500 response code indicates the service is down.

Endpoint: /public/api/v0/healthcheck

Success:
Response Code: 200

Body: {"ok": true}

Error:
Response Code: 403|500


Repositories Endpoint


Query for all repositories associated with a given API key.

Endpoint: /public/api/v0/repositories

Success:
Response Code: 200

Types:

interface Repository {
  id: string;
  name: string;
  defaultBranchId: string;
}


Body:

interface RepositoriesResponse {
  repositories: Array<Repository>;
  apiTrackingId: string; // included in remote API only
}


Error:
Response Code: 403|500


Repository Endpoint


Query a single repository with the repositoryId.

Endpoint: /public/api/v0/repository/:repositoryId

Slug Params:
repositoryId - uuid of the floro repository

Success:
Response Code: 200

Types:

interface Repository {
  id: string;
  name: string;
  defaultBranchId: string;
}


Body:

interface RepositoryResponse {
  repository: Repository;
  apiTrackingId: string; // included in remote API only
}


Error:
Response Code: 403|404|500


Branches Endpoint


Query all the current branches of a repository.

Endpoint: /public/api/v0/repository/:repositoryId/branches

Slug Params:
repositoryId - uuid of the floro repository

Success:
Response Code: 200

Types:

interface Branch {
  id: string;
  name: string;
  lastCommit: string|null;
  createdBy: string; // floro user uuid
  createdByUsername: string; // floro user username
  createdAt: string; // ISO DateTime UTC
  baseBranchId: string|null;
}


Body:

interface BranchesResponse {
  branches: Array<Branch>;
  apiTrackingId: string; // included in remote API only
}


Error:
Response Code: 403|404|500


Branch Endpoint


Query branch of a repository.

Endpoint: /public/api/v0/repository/:repositoryId/branch/:branchId

Slug Params:
repositoryId - uuid of the floro repository
branchId - string id of the branch

Success:
Response Code: 200

Types:

interface Branch {
  id: string;
  name: string;
  lastCommit: string|null;
  createdBy: string; // floro user uuid
  createdByUsername: string; // floro user username
  createdAt: string; // ISO DateTime UTC
  baseBranchId: string|null;
}


Body:

interface BranchResponse {
  branch: Branch;
  apiTrackingId: string; // included in remote API only
}


Error:
Response Code: 403|404|500


Commit Endpoint


Query commit info from repository.

Endpoint: /public/api/v0/repository/:repositoryId/commit/:sha

Slug Params:
repositoryId - uuid of the floro repository
sha - sha-256 floro commit sha

Success:
Response Code: 200

Types:

interface Commit {
  sha: string; // sha-256
  originalSha: string|null; // sha-256
  parent: string|null; // sha-256
  historicalParent: string|null; // sha-256
  idx: number; // commit index
  mergeBase: string|null;// sha-256
  mergeRevertSha: string|null;// sha-256
  revertFromSha: string|null;// sha-256
  revertToSha: string|null;// sha-256
  message: string;
  username: string;
  authorUsername: string;
  timestamp: string; // ISO DateTime UTC
  authorUserId: string; // floro user uuid
  userId: string; // floro user uuid
}


Body:

interface CommitResponse {
  commit: Commit;
  apiTrackingId: string; // included in remote API only
}


Error:
Response Code: 403|404|500


Commit State Link Endpoint


Query for a link to retrieve the repository state of the commit.

In the remote api. the state link is a signed url to retrieve the commit state from the CDN.

In the local api, the returned link uses the hostname https://<your_local_ip>:63405. Floro runs on port 63403 unencrypted and only listens on the loopback interface. Floro also runs over tls (for some endpoints) on 63405 and accepts traffic on all interfaces. This means in development you need to make sure you either trust your local floro tls cert or make sure when you fetch state you disable SSL verification. You could also just replace https with http and 63405 with 63403 from the returned stateLink, if that makes sense for your use case.

Endpoint: /public/api/v0/repository/:repositoryId/commit/:sha/stateLink

Slug Params:
repositoryId - uuid of the floro repository
sha - sha-256 floro commit sha

Success:
Response Code: 200

Body:

interface StateLinkResponse {
  stateLink: string; // signed CDN url (remote) or state url (local)
  apiTrackingId: string; // included in remote API only
}


Error:
Response Code: 403|404|500

State Link Body:

interface State {
  binaries: Array<string>;
  description: Array<string>;
  licenses: Array<{key: string, value: string}>;
  plugins: Array<{key: string, value: string}>;
  store: {
    [pluginName: string]: PluginStateTree; // this is specific to the schemas of the plugins your repository consumes
  }
}



Binaries Endpoint


Query for a list of binaries used in the commit. Binaries are a part of the plugin state but are external resources to the state. Binaries can also be plain text. For example a .svg file is considered a binary in floro. Floro will use the content-type of the binary for the response.

In the remote api. the urls are signed urls to retrieve the binary from the CDN.

In the local api, the returned link for a binary uses the hostname http://127.0.0.1:63403 along with an access token.


Endpoint: /public/api/v0/repository/:repositoryId/commit/:sha/binaries

Slug Params:
repositoryId - uuid of the floro repository
sha - sha-256 floro commit sha

Success:
Response Code: 200

Types:

interface Binary {
  hash: string; // sha-256 hash of file contents
  fileName: string;
  url: string; // signed CDN url (remote) or url with access token (local)
}


Body:

interface BinariesResponse {
  binaries: Array<Binary>;
  apiTrackingId: string; // included in remote API only
}


Error:
Response Codes: 403|404|500


Manifests Endpoint


Query for a list of all plugin manifests used in the commit.

Plugin manifests describe the schemas of the plugins used in a given commit.

Endpoint: /public/api/v0/repository/:repositoryId/commit/:sha/manifests

Slug Params:
repositoryId - uuid of the floro repository
sha - sha-256 floro commit sha

Success:
Response Code: 200

Types:

export interface ManifestNode {
  type: string;
  isKey?: boolean;
  values?: string | TypeStruct;
  ref?: string;
  refKeyType?: string;
  refType?: string;
  nullable?: boolean;
  emptyable?: boolean;
  bounded?: boolean;
  manualOrdering?: boolean;
  onDelete?: "delete" | "nullify";
  default?: unknown|Array<unknown>;
}

export interface TypeStruct {
  [key: string]: ManifestNode | TypeStruct;
}

export interface Manifest {
  version: string;
  name: string;
  displayName: string;
  description?: string;
  codeDocsUrl?: string;
  codeRepoUrl?: string;
  managedCopy?: boolean;
  icon:
    | string
    | {
        light: string;
        dark: string;
        selected?:
          | string
          | {
              dark?: string;
              light?: string;
            };
      };
  imports: {
    [name: string]: string;
  };
  types: TypeStruct; // this is the floro schema language (documentation coming soon)
  store: TypeStruct; // this is the floro schema language (documentation coming soon)
  seed?: unknown; // this is the initial default value of the plugin state post installation
}


Body:

interface ManifestResponse {
  manifests: Array<Manifest>;
  apiTrackingId: string; // included in remote API only
}


Error:
Response Code: 403|404|500


Root Schema Map Endpoint


Query for the root schema map of the commit state.

We will add further documentation after we formalize our plugin & generator APIs. For now know that this is the combined & normalized schema of all the schema manifests for the given commit.

Endpoint: /public/api/v0/repository/:repositoryId/commit/:sha/rootSchemaMap

Slug Params:
repositoryId - uuid of the floro repository
sha - sha-256 floro commit sha

Success:
Response Code: 200

Types:

export interface RootSchemaMap {
  [pluginName: string]: TypeStruct; // this is specific to the schemas of the plugins your repository consumes
}


Body:

interface ManifestResponse {
  rootSchemaMap: RootSchemaMap;
  apiTrackingId: string; // included in remote API only
}


Error:
Response Code: 403|404|500


Invalidity Map Endpoint


Query for the invalidity map of the commit state.

We will add further documentation after we formalize our plugin & generator APIs. For now know that this returns the list of floro plugin keys pointing to the invalid parts of the state.

This is useful in the case of real-time updates in determining if it is safe to live update some piece of state.

Endpoint: /public/api/v0/repository/:repositoryId/commit/:sha/invalidityMap

Slug Params:
repositoryId - uuid of the floro repository
sha - sha-256 floro commit sha

Success:
Response Code: 200

Types:

export interface InvalidityMap {
  [pluginName: string]: Array<string>; // list of plugin keys that are marked invalid
}


Body:

export interface InvalidityMapResponse {
  invalidityMap: InvalidityMap;
  apiTrackingId: string; // included in remote API only
}


Error:
Response Code: 403|404|500


Is Topological Subset Endpoint


Query between two shas to determine if the plugin state of the second sha (forward sha) is a topological subset of the first sha for a given plugin.

We will add further documentation after we formalize our plugin & generator APIs.

This is a useful endpoint for determining if a commit is safe to update to in production. It determines if a forward state is compatible with a current state.

For example, if we build an app using a set of icons A, B, and C and in a future commit icon B was removed, we could use this endpoint to determine that it is unsafe to update the production state to the forward commit. It is particularly useful when a plugin has upstream dependencies that may affect the state topology.

Endpoint: /public/api/v0/repository/:repositoryId/commit/:sha/isTopologicalSubset/:forwardSha/:pluginId

Slug Params:
repositoryId - uuid of the floro repository
sha - sha-256 floro commit sha
forwardSha - sha-256 floro commit sha of forward state
pluginId - plugin name that this is being queried for

Success:
Response Code: 200

Body:

export interface IsTopologicalSubsetResponse {
  isTopologicalSubset: boolean;
  apiTrackingId: string; // included in remote API only
}


Error:
Response Code: 403|404|500


Is Topological Subset Valid Endpoint


Query between two shas to determine if the plugin state of the second sha (forward sha) is a topological subset of the first sha for a given plugin and check that the forward commit's plugin state is valid.

We will add further documentation after we formalize our plugin & generator APIs.

See the last endpoint for more details. A plugin state is considered invalid if it's invalidity map is not empty.

Endpoint: /public/api/v0/repository/:repositoryId/commit/:sha/isTopologicalSubsetValid/:forwardSha/:pluginId

Slug Params:
repositoryId - uuid of the floro repository
sha - sha-256 floro commit sha
forwardSha - sha-256 floro commit sha of forward state
pluginId - plugin name that this is being queried for

Success:
Response Code: 200

Body:

export interface IsTopologicalSubsetValidResponse {
  isTopologicalSubsetValid: boolean;
  apiTrackingId: string; // included in remote API only
}


Error:
Response Code: 403|404|500


Webhooks



As mentioned in the overview there is only one floro webhook (aside from the test webhook). The only production webhook is emitted when a branch is updated. You can use this webhook to know when to pull changes from a floro branch.

You must respond to the webhook with a 200 response code in less than 5 seconds. The webhook will be re-attempted exponentially but will only be attempted 3 times.

The webhook will contain a header signature called Floro-Signature-256. The signature is the hmac sha-256 signature of the json payload, using your webhook secret. The signature is prefixed like so sha-256=<signature>. You can find examples of validating the signature in the Remix & Next demo repositories linked in the integration docs.

Events

//types
interface Branch {
  id: string;
  name: string;
  lastCommit: string|null;
  createdBy: string; // floro user uuid
  createdByUsername: string; // floro user username
  createdAt: string; // ISO DateTime UTC
  baseBranchId: string|null;
}

//events
export interface TestWebhookEvent {
  event: "test";
  repositoryId: string;
  payload: {};
}

export interface BranchUpdatedWebhook {
  event: "branch.updated";
  repositoryId: string;
  payload: {
    branch: Branch;
  };
}