Skip to content

Webhooks

Webhook Setup

Partners are able to register multiple webhook subscriptions per account; these subscriptions must be unique by URL per partner. We do not currently support scoping per webhook subscription, so all webhook events will be sent to every endpoint the partner has registered. Subscription to specific webhook scopes is coming soon.

Follow the steps below to set up webhooks for your Basic Capital integration.

1. Add a Webhook Handler

Webhooks do not contain any details on the triggered event. Instead, they provide the event type, entity ID, and information about the owner of the data. Together, these provide the information necessary in order to pull the event details from Basic Capital.

Webhook events will be in the following format:

POST /your/configured/webhook/endpoint
X-BC-Webhook-Validation-Token: "sample_validation_token"

{
  "owner_uuid": "string",
  "scope": "PARTNER | COMPANY | EMPLOYEE",
  "object_uuid": "string",
  "event_type": "EventType",
  "timestamp": "string",
  "request_id": "string"
}


Field definitions:

FieldDescription
owner_uuidThe entity this event belongs to; pass this in the X-Identity-Uuid header when requesting the data
scopeThe identity type this event belongs to; pass this in the X-Identity-Type header when requesting the data
object_uuidThe actual object the event is referencing; used to fetch specific event
event_typeThe type of event that occurred; we indicate which endpoints owns each event type below
timestampWhen the communication was sent, not when the event occurred. Used for authenticating the webhook request
request_idUnique ID for each webhook message request

2. Webhook Verification

While it is not strictly required, we strongly recommend that partners implement verification on incoming webhooks. Each webhook will carry the following JWT header:

X-BC-Webhook-Validation-Token: "sample_validation_jwt"


Verify as follows:

  1. Fetch Basic Capital's public key via GetWebhookValidationContext (gRPC). We recommend caching this value.
  2. Use the public key to decode the JWT, which will have the following format
    {
      "requestId": "string",
      "timestamp": "string"
    }
  3. Verify the timestamp, which will be in epoch milliseconds. Reject requests older than 5 minutes.
  4. Verify the requestId is unique.
  5. Verify timestamp and requestId values match what is in the request body.

3. Register Your Webhook

  1. Register a new webhook at CreateWebhookSubscription (gRPC)
  2. On registration, Basic Capital will send a webhook message to the url with event type VERIFY_WEBHOOK. This endpoint must return a 200, or the subscription will not be created.

4. Removing Stale Webhook Registrations

Webhooks will be created if the initial VERIFY_WEBHOOK event returns a 200. However, if a webhook endpoint begins to fail consistently, it will eventually be deactivated. We recommend that you remove old webhooks for clarity; this will help Basic Capital give the best support for your integration. Webhook subscriptions can be paused, reactivated, or deleted via SetWebhookSubscriptionStatus (gRPC).

You can list your current webhooks at any time at ListWebhookSubscriptions (gRPC).

Webhook Event Types

New webhook event types may be added in the future. We recommend implementations ignore unknown event types instead of erroring, to ensure they remain compatible.

Event TypeDescriptionScopeEndpoint
VERIFY_WEBHOOKInitial verification. Must return a 200.n/an/a
ALERT_ACTION_REQUIREDRequired action in Basic Capital dashboardCOMPANY or EMPLOYEELog into Basic Capital
ALERT_INFORMATIONALNew alert, no action requiredCOMPANY or EMPLOYEELog into Basic Capital
EMPLOYEE_STATUS_CHANGEChange to employee's statusCOMPANYGetEmployeeDetails
EMPLOYEE_ONBOARDING_STATUS_CHANGEChange to employee's onboarding progressEMPLOYEEGetEmployeeOnboardingStatus
CONTRIBUTION_CONFIG_UPDATEDUpdate to employee's contributionsEMPLOYEEGetEmployeeContributionRates
COMPANY_ONBOARDING_STATUS_CHANGEAsync updates during company onboardingCOMPANYGetCompanyOnboardingStatus
PLAN_CONFIGURATION_STATUS_CHANGEUpdates to plan configuration statusCOMPANYGetCompanyOnboardingStatus

Webhook API documentation

CreateWebhookSubscription

Create a new webhook subscription. Will fail if the partner already has a subscription with this URL.

service PartnerIngressService {
  rpc CreateWebhookSubscription(CreateWebhookSubscriptionRequest) returns (CreateWebhookSubscriptionResponse);
}

message CreateWebhookSubscriptionRequest {
  string url = 1;
}

message CreateWebhookSubscriptionResponse {
  WebhookSubscription webhook_subscription = 1;
}

Data types: WebhookSubscription

GetWebhookSubscription

service PartnerIngressService {
  rpc GetWebhookSubscription(GetWebhookSubscriptionRequest) returns (GetWebhookSubscriptionResponse);
}

message GetWebhookSubscriptionRequest {
  string uuid = 1;
}

message GetWebhookSubscriptionResponse {
  optional WebhookSubscription webhook_subscription = 1;
}

Data types: WebhookSubscription

ListWebhookSubscriptions

Returns all subscriptions for a partner. Includes paused subscriptions.

service PartnerIngressService {
  rpc ListWebhookSubscriptions(ListWebhookSubscriptionsRequest) returns (ListWebhookSubscriptionsResponse);
}

message ListWebhookSubscriptionsRequest {}

message ListWebhookSubscriptionsResponse {
  repeated WebhookSubscription webhook_subscriptions = 1;
}

Data types: WebhookSubscription

UpdateWebhookSubscription

Update the URL for a subscription. Errors if the URL is already registered.

service PartnerIngressService {
  rpc UpdateWebhookSubscription(UpdateWebhookSubscriptionRequest) returns (UpdateWebhookSubscriptionResponse);
}

message UpdateWebhookSubscriptionRequest {
  string uuid = 1;
  string url = 2;
}

message UpdateWebhookSubscriptionResponse {
  WebhookSubscription webhook_subscription = 1;
}

Data types: WebhookSubscription

SetWebhookSubscriptionStatus

Pause, reactivate, or delete a subscription.

service PartnerIngressService {
  rpc SetWebhookSubscriptionStatus(SetWebhookSubscriptionStatusRequest) returns (SetWebhookSubscriptionStatusResponse);
}

message SetWebhookSubscriptionStatusRequest {
  enum StatusUpdate {
    UNKNOWN_STATUS_UPDATE = 0;
    REACTIVATE = 1;
    PAUSE = 2;
    DELETE = 3;
  }

  string uuid = 1;
  StatusUpdate status_update = 2;
}

message SetWebhookSubscriptionStatusResponse {
  WebhookSubscription webhook_subscription = 1;
}

Data types: WebhookSubscription

GetWebhookValidationContext

Fetch the public key for webhook signature validation. Cache this value.

service PartnerIngressService {
  rpc GetWebhookValidationContext(GetWebhookValidationContextRequest) returns (GetWebhookValidationContextResponse);
}

message GetWebhookValidationContextRequest {}

message GetWebhookValidationContextResponse {
  string public_key = 1;
}

WebhookSubscription

Partner-facing webhook subscription. DEV_TEST is surfaced as ACTIVE. DELETED is only ever returned in the immediate response to a SetWebhookSubscriptionStatus delete; Get/List exclude DELETED subscriptions.

message WebhookSubscription {
  enum Status {
    UNKNOWN_STATUS = 0;
    ACTIVE = 1;
    ERRORED = 2;
    PAUSED = 3;
    DELETED = 4;
  }

  string uuid = 1;
  string url = 2;
  Status status = 3;
  optional string notes = 4;
}