Reverse ETL allows the use of a database (aka: Segment Warehouse) as a source of data to be connected and sent to supported Segment Destinations. Previously, it was only possible to use a Segment Warehouse as a destination.
The structure of config
varies with the value in strategy
.
All strategies will employ a key/value object with minimum depth of 1.
When strategy
is "manual", config
can be excluded altogether. With
this strategy, syncs will never be triggered automatically, so they must be
triggered manually through the UI or Public API route.
"reverseETLSchedule": {
"strategy": "manual"
}
When strategy
is "periodic", the only supported config
key is "interval",
which will be a string that is in a format accepted by Go's
time.ParseDuration function. For example, "3h" will
sync every 3 hours, while "30m" will sync every 30 minutes. The interval must be
greater than 10 minutes ("10m") and shorter than 1 week ("168h").
An example schedule would look like this:
"reverseETLSchedule": {
{
"config": {
"interval": "1h"
},
"strategy": "periodic"
}
}
When strategy
is "specific_days", there are only 3 supported config
keys:
"days", "hours" and "timezone".
The "days" field must be an array of numbers, corresponding to the desired days of the week that syncs should run. Each item must be a number from 0 (Sunday) up to 6 (Saturday). There needs to be at least 1 item, but also no more than 7.
For example: [0, 6]
would correspond to the weekend (Saturday and Sunday)
while [1, 2, 3, 4, 5]
would correspond to the weekdays (Monday through
Friday).
The "hours" field must be an array of numbers, corresponding to the desired hours of the day that syncs should run. Each item must be a number from 0 (12am or 0:00) up to 23 (11pm or 23:00). There needs to be at least 1 item, but also no more than 24.
For example: [0, 12]
would correspond to the running at midnight (12:00am /
0:00) and noon (12:00pm / 12:00).
The "timezone" field must be a valid value from the IANA database used by Golang, which should match the list found here. This allows the "hours" above to reflect your own time zone which may be easier to configure, but you can also choose "UTC" if you want to avoid things like DST (daylight savings).
A simple example config would look like:
"reverseETLSchedule": {
"config": {
"days": [1],
"hours": [15],
"timezone": "America/New_York"
},
"strategy": "specific_days"
}
A more complex example:
"reverseETLSchedule": {
"config": {
"days": [0, 6],
"hours": [0, 6, 12, 18],
"timezone": "America/Los_Angeles"
},
"strategy": "specific_days"
}
This would run syncs 4 times per day (midnight, 6am, noon, 6pm) but only on weekends (Saturday and Sunday).
Use the cron
expression for precise scheduling. Remember to include only five fields, not six, as Segment's smallest time unit is minutes. If you need help, use a cron expression generator to create the ideal schedule.
Note: We do not allow cron expressions lower than 15 minutes.
Here is an example indicating 'At 15 minutes past the hour, every 3 hours, on day 1 of the month', e.g. (Tuesday October 01, 2024 at 12:15 am)
"reverseETLSchedule": {
"config": {
"spec": "15 */3 1 * *",
"timezone": "America/Los_Angeles"
},
"strategy": "cron"
}
Triggers a manual sync for a Reverse ETL Connection.
In the request body, the subscription id
is the id that follows after /mappings/
portion in the URL of the sync.
For example, the subscription id
would be 2
for this sync: https://app.Segment.com/example-workspace/reverse-etl/destinations/example-destination/sources/example-source/instances/1/mappings/2/source-id/3/model-id/4/sync-details
The rate limit for this endpoint is 20 requests per minute, which is lower than the default due to access pattern restrictions. Once reached, this endpoint will respond with the 429 HTTP status code with headers indicating the limit parameters. See Rate Limiting for more information.
OK
Resource not found
Validation failure
Too many requests
{- "sourceId": "sourceId",
- "modelId": "modelId",
- "subscriptionId": "subscriptionId"
}
{- "data": {
- "reverseETLManualSync": {
- "startedAt": "2023-11-22T01:07:19.571346969Z",
- "syncId": "startjob-2YVeaiMPrApykGSvVlY6bCcEtvd"
}
}
}
Creates a new Reverse ETL Model.
• When called, this endpoint may generate the Model Created
event in the audit trail.
Created
Resource not found
Validation failure
Too many requests
{- "sourceId": "qQEHquLrjRDN9j1ByrChyn",
- "name": "Model 1",
- "description": "This model is very useful.",
- "enabled": true,
- "query": "SELECT 'user_1' AS id",
- "queryIdentifierColumn": "id"
}
{- "data": {
- "reverseEtlModel": {
- "id": "pmoNLgeTB2AGfSDgoTT6qA",
- "sourceId": "qQEHquLrjRDN9j1ByrChyn",
- "name": "Model 1",
- "description": "This model is very useful.",
- "enabled": true,
- "query": "SELECT 'user_1' AS id",
- "queryIdentifierColumn": "id"
}
}
}
Returns a list of Reverse ETL Models.
object (PaginationInput) Defines the pagination parameters. This parameter exists in alpha. Example: pagination=pagination.count=10 |
OK
Resource not found
Validation failure
Too many requests
import { configureApis, unwrap } from '@segment/public-api-sdk-typescript' const api = configureApis('/* Insert your Public API token here */') try { const result = await unwrap(api.reverseEtl.listReverseEtlModels()) console.log(JSON.stringify(result)) } catch (e) { console.log('ERROR:', e) }
{- "data": {
- "models": [
- {
- "id": "2QfwyeQY3Keba1qZx3BNbp",
- "sourceId": "qQEHquLrjRDN9j1ByrChyn",
- "name": "Model 1",
- "description": "This model is very useful.",
- "enabled": true,
- "query": "SELECT 'user_1' AS id",
- "queryIdentifierColumn": "id"
}
], - "pagination": {
- "current": "MA==",
- "totalEntries": 1
}
}
}
Deletes an existing Model.
• When called, this endpoint may generate the Model Deleted
event in the audit trail.
OK
Resource not found
Validation failure
Too many requests
import { configureApis, unwrap } from '@segment/public-api-sdk-typescript' const api = configureApis('/* Insert your Public API token here */') try { const result = await unwrap(api.reverseEtl.deleteReverseEtlModel('fxXMc5bLdKnDfEgBpDbV11')) console.log(JSON.stringify(result)) } catch (e) { console.log('ERROR:', e) }
{- "data": {
- "status": "SUCCESS"
}
}
Returns a Reverse ETL Model by its id.
OK
Resource not found
Validation failure
Too many requests
import { configureApis, unwrap } from '@segment/public-api-sdk-typescript' const api = configureApis('/* Insert your Public API token here */') try { const result = await unwrap(api.reverseEtl.getReverseEtlModel('jSAVzDH3z89geNDZwoNY9V')) console.log(JSON.stringify(result)) } catch (e) { console.log('ERROR:', e) }
{- "data": {
- "reverseEtlModel": {
- "id": "jSAVzDH3z89geNDZwoNY9V",
- "sourceId": "qQEHquLrjRDN9j1ByrChyn",
- "name": "Model 1",
- "description": "This model is very useful.",
- "enabled": true,
- "query": "SELECT 'user_1' AS id",
- "queryIdentifierColumn": "id"
}
}
}
Updates an existing Reverse ETL Model.
• When called, this endpoint may generate one or more of the following audit trail events:* Model Settings Saved
OK
Resource not found
Validation failure
Too many requests
{- "name": "My Updated Model",
- "query": "SELECT 'user_2' AS id"
}
{- "data": {
- "reverseEtlModel": {
- "id": "6BthE21tPsXyA2cK3QPQFQ",
- "sourceId": "qQEHquLrjRDN9j1ByrChyn",
- "name": "My Updated Model",
- "description": "This model is very useful.",
- "enabled": true,
- "query": "SELECT 'user_2' AS id",
- "queryIdentifierColumn": "id"
}
}
}
Get the sync status for a Reverse ETL sync. The sync status includes all detailed information about the sync - sync status, duration, details about the extract and load phase if applicable, etc.
The rate limit for this endpoint is 250 requests per minute, which is lower than the default due to access pattern restrictions. Once reached, this endpoint will respond with the 429 HTTP status code with headers indicating the limit parameters. See Rate Limiting for more information.
OK
Resource not found
Validation failure
Too many requests
import { configureApis, unwrap } from '@segment/public-api-sdk-typescript' const api = configureApis('/* Insert your Public API token here */') try { const result = await unwrap(api.reverseEtl.getReverseETLSyncStatus('modelId', 'syncId')) console.log(JSON.stringify(result)) } catch (e) { console.log('ERROR:', e) }
{- "data": {
- "reverseETLSyncStatus": {
- "sourceId": "qQEHquLrjRDN9j1ByrChyn",
- "modelId": "pUy1F8Xsy3cLR25QBDNsbN",
- "syncId": "1",
- "syncStatus": "SUCCESS",
- "duration": "21.481s",
- "error": "",
- "errorCode": "",
- "startedAt": "2024-01-25T18:58:10.16064Z",
- "finishedAt": "2024-01-25T18:58:31.64138Z",
- "extractPhase": {
- "addedCount": "1000",
- "updatedCount": "0",
- "deletedCount": "0",
- "extractCount": "1000",
- "errorCode": "",
- "startedAt": "2024-01-25T18:58:10.31623Z",
- "finishedAt": "2024-01-25T18:58:20.692479Z"
}, - "loadPhase": {
- "deliverSuccessCount": "1000",
- "deliverFailureCount": "0",
- "errorCode": "",
- "startedAt": "2024-01-25T18:58:20.84456Z",
- "finishedAt": "2024-01-25T18:58:31.64138Z"
}
}
}
}
Get the sync statuses for a Reverse ETL mapping subscription.
The sync status includes all detailed information about the sync - sync status, duration, details about the extract and load phase if applicable, etc.
The default page count is 10, and then the next page can be fetched by passing the cursor
query parameter.
OK
Resource not found
Validation failure
Too many requests
import { configureApis, unwrap } from '@segment/public-api-sdk-typescript' const api = configureApis('/* Insert your Public API token here */') try { const result = await unwrap(api.reverseEtl.listReverseETLSyncStatusesFromModelAndSubscriptionId('modelId', 'subscriptionId')) console.log(JSON.stringify(result)) } catch (e) { console.log('ERROR:', e) }
{- "data": {
- "syncStatuses": [
- {
- "sourceId": "qQEHquLrjRDN9j1ByrChyn",
- "modelId": "pUy1F8Xsy3cLR25QBDNsbN",
- "syncId": "1",
- "syncStatus": "SUCCESS",
- "duration": "21.481s",
- "error": "",
- "errorCode": "",
- "startedAt": "2024-01-25T18:58:10.16064Z",
- "finishedAt": "2024-01-25T18:58:31.64138Z",
- "extractPhase": {
- "addedCount": "1000",
- "updatedCount": "0",
- "deletedCount": "0",
- "unmodifiedCount": "0",
- "extractCount": "1000",
- "errorCode": "",
- "startedAt": "2024-01-25T18:58:10.31623Z",
- "finishedAt": "2024-01-25T18:58:20.692479Z"
}, - "loadPhase": {
- "deliverSuccessCount": "1000",
- "deliverFailureCount": "0",
- "errorCode": "",
- "startedAt": "2024-01-25T18:58:20.84456Z",
- "finishedAt": "2024-01-25T18:58:31.64138Z"
}
}
], - "pagination": {
- "current": "2024-01-25T18:58:20.84456Z",
- "next": "2024-01-25T19:58:20.84456Z"
}
}
}