Skip to main content

Code-Native Endpoint Configuration

By default, instances of integrations that you deploy will be assigned unique webhook URLs - one URL for each flow. We call this Instance and Flow Specific endpoint configuration. Alternatively, you can choose Instance Specific endpoint configuration (each instance gets its own webhook URL and all flows share the single URL) or Shared endpoint configuration, where all flows of all instances share one URL.

To specify endpoint type, add an endpointType property to the integration() definition in src/index.ts. It can have values "instance_specific", "flow_specific" or "shared_instance", and defaults to "flow_specific":

import { integration } from "@prismatic-io/spectral";
import flows from "./flows";
import { configPages } from "./configPages";

export default integration({
name: "shared-endpoint-example",
description: "Shared Endpoint Example",
iconPath: "icon.png",
flows,
configPages,
componentRegistry,
endpointType: "instance_specific",
});

When Instance Specific or Shared endpoint configuration is selected, you need some logic to determine which flow (and which customer's instance in the case of Shared) should be run. This can be done with or without a preprocess flow, and both methods are described below.

Full documentation on endpoint configuration is available in the Endpoint Configuration article.

Endpoint configuration in code-native without preprocess flow

If the flow that you want to run is specified in the webhook request's body or in a header, you can configure shared endpoint without a preprocess flow. If, for example, the flow you want to run is specified using a header named x-acme-flow, note that header's name in your integration definition using the triggerPreprocessFlowConfig property:

Instance specific endpoint configuration without a preprocess flow
export default integration({
name: "shared-endpoint-example",
description: "Shared Endpoint Example",
iconPath: "icon.png",
flows,
configPages,
componentRegistry,
endpointType: "instance_specific",
triggerPreprocessFlowConfig: {
flowNameField: "headers.x-acme-flow",
},
});

To invoke an instance of an execution that has been deployed, this curl command would invoke the flow named "Create Opportunity":

Invoke an instance specific endpoint with a flow name specified in a header
curl https://hooks.prismatic.io/trigger/SW5ExampleInstanceSpecificEndpoint \
-X POST \
--header "content-type: application/json" \
--header "x-acme-flow: Create Opportunity" \
--data '{
"opportunity": {
"name": "Foo",
"amount": 10000
}
}'

If all of your instances share an endpoint, you can similarly specify a customer external ID from the request body or headers:

Shared endpoint configuration without a preprocess flow
export default integration({
name: "shared-endpoint-example",
description: "Shared Endpoint Example",
iconPath: "icon.png",
flows,
configPages,
componentRegistry,
endpointType: "shared_instance",
triggerPreprocessFlowConfig: {
flowNameField: "headers.x-acme-flow",
externalCustomerIdField: "body.data.acmeAccountId",
},
});
Invoke an shared endpoint with a flow name header and customer ID in the body
curl https://hooks.prismatic.io/trigger/SW5ExampleSharedEndpoint \
-X POST \
--header "content-type: application/json" \
--header "x-acme-flow: Create Opportunity" \
--data '{
"acmeAccountId": "abc-123",
"opportunity": {
"name": "Foo",
"amount": 10000
}
}'

Endpoint configuration in code-native with preprocess flow

A preprocess flow allows you to run custom logic to determine which flow should be run (and in the case of Shared endpoint config, which customer should be run). One of your flows can look at the request body or headers, make API calls, etc., and then return the name of the flow (and customer) to run.

If you use a preprocess flow, one (and exactly one) of your flows must be marked as the preprocess flow. You cannot specify both a preprocess flow and a triggerPreprocessFlowConfig property.

This example preprocess flow has an onExecution function (like any other flow). This flow returns two properties: myFlowName and myCustomerId - you can name those properties whatever you like. These property preprocessFlowConfig specifies which properties to look for in the response from the preprocess flow:

Shared endpoint configuration with a preprocess flow
import axios from "axios";
import { flow } from "@prismatic-io/spectral";

const flowMapper = {
create_opportunity: "Create Opportunity",
update_opportunity: "Update Opportunity",
};

interface CreateOpportunityPayload {
event: "create_opportunity";
acctId: string;
opportunity: {
name: string;
amount: number;
};
}

interface UpdateOpportunityPayload {
event: "update_opportunity";
acctId: string;
opportunity: {
id: string;
name: string;
amount: number;
};
}

type Payload = CreateOpportunityPayload | UpdateOpportunityPayload;

export const myPreprocessFlow = flow({
name: "My Preprocess Flow",
stableKey: "my-preprocess-flow",
preprocessFlowConfig: {
flowNameField: "myFlowName",
externalCustomerIdField: "myCustomerId",
},
description: "This determines which sibling flow should be invoked",
onExecution: async (context, params) => {
const { event, acctId } = params.onTrigger.results.body.data as Payload;
const customerIdResponse = await axios.post(
"https://api.example.com/get-customer-id",
{
acmeAcctId: acctId,
},
);

return Promise.resolve({
data: {
myFlowName: flowMapper[event],
myCustomerId: customerIdResponse.data.customerId,
},
});
},
});

The above preprocess flow will look at a property named event in the request body and map an event of create_opportunity to the string Create Opportunity, returning Create Opportunity as the name of the flow to run. It will also extract an acctId from the request body and make an HTTP request to https://api.example.com/get-customer-id to get an external customer ID, returning that customer ID as well.

curl https://hooks.prismatic.io/trigger/SW5ExampleSharedEndpoint \
-X POST \
--header "content-type: application/json" \
--data '{
"event": "create_opportunity",
"acctId": "abc-123",
"opportunity": {
"name": "Foo",
"amount": 10000
}
}'

To create a preprocess flow for Instance Specific endpoint configuration, omit the externalCustomerIdField property from the preprocessFlowConfig object.