Custom data sync destinations
Build an Optimizely Connect Platform (OCP) app that creates custom destinations that users who install your app can use in data syncs.
After you import data into Optimizely Connect Platform (OCP), you can configure data syncs to sync that data out of OCP and into other applications (Optimizely or external). Every data sync has the following two base components:
- Source – Where you want to sync the data from, such as the OCP database.
- Destination – Where you want to sync the data to, such as an Optimizely application or custom destinations defined in your custom OCP app.
Building a custom OCP app lets you define custom destinations that users who install your app can select as a destination on the Sync Manager page in OCP.
You can add a custom destination to your OCP app in three steps:
- Declare destinations in the app manifest file (
app.yml
). - Declare the schema for your destinations (one schema per destination).
- Implement the logic for the destinations.
Prerequisite
Register and scaffold your app.
Declare destinations in the app manifest file
You can define multiple destinations in a single app. You must declare every destination in the destinations
section of the app manifest file (app.yml
), and each destination must have its own schema and logic.
Required properties
schema
– Must match a schema name defined insrc/destinations/schemas
.entry_point
– Name of the class implementing the sync logic.
Optional properties
description
– Human-readable sync purpose.
For example:
destinations:
bynder_asset_sync:
entry_point: BynderAssetSync
description: Sync Assets to Bynder
schema: asset
When a user installs your app, any destinations you defined in the app will display in the Destinations drop-down list on the Sync Manager page in OCP.

Declare the schema
Schema is where you define which properties your destinations accept, which then display as options in the data sync field mappings. OCP calls your destination class method with properties defined in your schema.

You must create a matching YAML file in src/destinations/schemas
for each schema
field you defined in the app.yml
file with the following:
name
– Unique identifier matching theschema
value in the manifest.display_name
– User-friendly name.description
– The field's purpose.fields
– Data structure and validation rules.type
– Type of value for the field. The following types are supported:string
boolean
int
float
long
primary
– Designates the unique identifier field for the object.
The following is an example for asset.yaml
schema:
name: asset
display_name: Asset
fields:
- name: bynder_id
type: string
display_name: Bynder Id
description: Primary Id in Bynder
primary: true
- name: bynder_asset_name
type: string
display_name: Bynder Asset Name
description: The name of the Asset
Implement the logic
Define your destination logic in a class that extends the Destination<T>
abstract class. OCP calls your destination class methods. The key method is deliver
, which accepts your list of items and should send the items to your destination service. Item property names match the fields you defined in your schema and are the values that display as options in the data sync field mappings.
Class structure
- Extend
Destination<T>
insrc/destinations
directory. - Match the class name with
entry_point
in the app manifest file (for example,BynderAssetSync
).
Methods to implement
ready()
- Check credentials and configuration validity.
- Return
DestinationReadyResult
withready: boolean
and errormessage
, if applicable.
deliver(batch: DestinationBatch<T>)
- Process
DestinationBatch<T>
containing the following:items[]
– List of items to process.attempt
– Count of delivery attempts.sync
–id
andname
of the data sync.
- Return
DestinationDeliverResult
with the following:success
– Indicates batch completion status.retriable
– Flag for retry eligibility on failure.failureReason
– (Optional) Internal error description.
- Process
For example:
import * as App from '@zaiusinc/app-sdk';
export interface BynderAsset {
id: string;
name: string;
}
export class BynderAssetSycn extends App.Destination<BynderAsset>{
public async ready(): Promise<App.DestinationReadyResult> {
return { ready: true };
}
public async deliver(batch: App.DestinationBatch<BynderAsset>): Promise<App.DestinationDeliverResult> {
return { success: true, retryable: false };
}
}
Handle errors and retries
Handle errors and retries in the deliver
method.
- Use
retriable: true
for transient errors (like network issues). A batch is retried a maximum of 3 times. - Set
retriable: false
for non-recoverable errors (like invalid credentials).
Directory Structure
- Destination classes –
src/destinations/{EntryPointClassName}.ts
- Schemas –
src/destinations/schema/*.yml
For example:
// successfully processed, no retry
return { success: true, retriable: false };
// unsuccesfully processed, no retry
return { success: false, retriable: false };
// unsuccessfully processed, retry
return { success: false, retriable: true };
Complete and publish your app
Updated 12 days ago