Skip to content

Commit 0db4174

Browse files
authored
Merge pull request #4831 from segmentio/thomas/direct-destination
Add page for new direct destination
2 parents 8b7b349 + c40a25d commit 0db4174

File tree

3 files changed

+176
-172
lines changed

3 files changed

+176
-172
lines changed

Gemfile.lock

Lines changed: 0 additions & 169 deletions
This file was deleted.

src/_data/sidenav/partners.yml

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ sections:
88
title: Conceptual model
99
- path: /partners/sources
1010
title: Build a Source
11-
- section_title: Build a Destination
11+
- path: /partners/direct-destination
12+
title: Build a Direct Destination
13+
- section_title: Build an Actions Destination
1214
slug: partners/subscriptions
1315
section:
1416
- path: /partners/destinations
@@ -17,8 +19,8 @@ sections:
1719
title: Build a Destination
1820
- path: /partners/destinations/testing
1921
title: Test a Destination
20-
- path: /partners/destinations/get-access
21-
title: Get Access
22+
# - path: /partners/destinations/get-access
23+
# title: Get Access
2224
- path: /partners/destinations/authentication
2325
title: Authentication
2426
# - path: /partners/plugins

src/partners/direct-destination.md

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
---
2+
title: Building a Direct Destination
3+
redirect_from: '/partners/build-webhook/'
4+
---
5+
6+
Direct Destinations allow Segment Partners to ingest Segment Event Data using just a webhook. This guide explains how to set up your webhook with Segment.
7+
8+
## Getting started
9+
10+
1. Apply to become a [Segment Select Partner](https://segment.com/partners/integration/){:target="_blank"}.
11+
2. Understand Segment's [Conceptual Model](/docs/partners/conceptual-model) and [Spec](/docs/connections/spec).
12+
3. [Request access to the Segment Developer Portal](https://segment.com/partners/developer-portal){:target="_blank"}.
13+
4. Once approved, select "Build a direct destination" within the [Developer Portal](https://app.segment.com/dev-portal/overview){:target="_blank"}.
14+
5. Build and test your Component(s).
15+
6. Add your catalog metadata.
16+
6. Publish documentation.
17+
7. Submit your Destination for review.
18+
8. Launch into _Public Beta_!
19+
20+
## Build
21+
22+
Begin by selecting "Build a direct destination" within the [Developer Portal](https://app.segment.com/dev-portal/overview). Next, you will see a field to input your destination name and slug (once created you will not be able to change the destination slug). Within the "Build and test" section of the portal UI, add the destination endpoint where Segment data will be forwarded to.
23+
24+
Continue reading below to understand what is expected when accepting and responding to Segment data.
25+
26+
### Accepting Segment Data
27+
28+
To receive data from Segment, you must provide a server with a static endpoint that can accept HTTPS requests.
29+
30+
The endpoint must:
31+
- *Accept POST requests.* Segment sends customer data to the endpoint you designate in POST requests.
32+
- *Accept JSON data.* Segment sends data in JSON.
33+
- *Use HTTPS.* Segment transmits potentially sensitive data on behalf of customers, and HTTPS is the first step in making sure their data stays safe.
34+
35+
#### Authorization
36+
37+
Segment sends your user's API key with requests, and you can use it to authenticate requests. This is the API key _you_ give to your users; it is not a Segment API key.
38+
39+
Segment sends the key in the `Authorization` header using the `Basic` authentication type. It is Base64 encoded with your user's API key as the username, and an empty password.
40+
41+
For example, if your user's API key was `segment`, Segment would Base64 encode the string `'segment:'` and prepend the string `'Basic '`. The colon is always present, even when the password is absent.
42+
43+
This would result in a final string of `'Basic c2VnbWVudDo='`. This is what is contained in the `Authorization` header. Like any Authorization header, you must decode the string when you receive it.
44+
45+
See the [headers](#headers) section for more details.
46+
47+
#### Custom settings
48+
All direct destinations have an API key setting by default, which Segment will send in the Authorization Header. To add more custom settings, go to the `Settings Editor` page. Any custom settings you add will be sent in the custom header `X-Segment-Settings` (See the [headers](#headers) section for more details.)
49+
50+
51+
#### Headers
52+
53+
Segment sends you the following HTTP headers with all requests:
54+
55+
| Header | Description | Example |
56+
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------- |
57+
| `Accept` | Segment accepts any content type, but ignores responses unless this header is set to `application/json`. | `Accept: */*` |
58+
| `Authorization` | Segment sends your user's API token in this header, with the `Basic` authentication type. | `Authorization: Basic c2VnbWVudDo=` |
59+
| `Cache-Control` | Each request Segment sends is a new event. Segment does not expect your application to cache. | `Cache-Control: no-cache` |
60+
| `Connection` | Segment uses HTTP/1.1's keep-alive functionality whenever possible, however this is optional. | `Connection: Keep-Alive` |
61+
| `Content-Length` | Segment always sends you the length of the request in bytes. | `Content-Length: 348` |
62+
| `Content-Type` | Segment indicates the type of data it sent you (this will always be JSON), along with Segment's vendor type. | `Content-Type: application/json` |
63+
| `User-Agent` | Segment sends you this field every time. | `User-Agent: Segment.io/1.0` |
64+
| `X-Segment-Settings` | Except for the API key (which is sent in the Authorization header), Segment will send the base 64 encoding of the rest of your custom settings encoded in this header. | `X-Segment-Settings: eyJjdXN0b21TZXR0aW5nT25lIjoiY3VzdG9tIHNldHRpbmcgdmFsdWUifQ==` |
65+
66+
67+
#### Request body
68+
69+
Segment's [Spec](/docs/connections/spec) standardizes the data that you can expect from Segment. You can choose to implement four types types of calls:
70+
71+
- Who is this? `.identify(userId, traits)`
72+
- What are they doing? `.track(userId, event, properties)`
73+
- Where are they doing it? `.page(userId, pageName, properties)`
74+
- What group are they part of? `.group(userId, groupId, groupTraits)`
75+
76+
For example, you might implement the `.identify(userId, traits)` call to create contacts in an email marketing application. You can expect the following customer information as a JSON object in the call body:
77+
78+
```json
79+
{
80+
"anonymousId": "1234",
81+
"context": {
82+
"ip": "8.8.8.8",
83+
"userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_9_5) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.115 Safari/537.36"
84+
},
85+
"messageId": "022bb90c-bbac-11e4-8dfc-aa07a5b093db",
86+
"receivedAt": "2015-02-23T22:28:55.387Z",
87+
"sentAt": "2015-02-23T22:28:55.111Z",
88+
"traits": {
89+
"name": "John Doe",
90+
"email": "[email protected]",
91+
"plan": "premium",
92+
"logins": 5
93+
},
94+
"type": "identify",
95+
"userId": "5678",
96+
"version": "1.1"
97+
}
98+
```
99+
100+
> info ""
101+
> The casing on these fields will vary by customer, so be ready to accept any casing.
102+
103+
104+
#### Status code
105+
106+
Segment uses standard HTTP status code conventions to help diagnose problems quickly and give better insight into how the destination is working.
107+
108+
Upon receiving data, your endpoint should reply with one of the following status codes:
109+
110+
| Code | Reason |
111+
| ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
112+
| `200` | You've accepted and successfully processed the message. |
113+
| `202` | You've accepted the message, but have not yet processed it. |
114+
| `400` | The message is malformed, or otherwise contains an error that is the client's fault. |
115+
| `401` | The client's API key is malformed, has expired, or is otherwise no longer valid. |
116+
| `403` | The client's API key is valid, but has been rejected due to inadequate permissions. |
117+
| `500` | If you encounter an internal error when processing the message, reply with this code. (Hopefully you won't have to send too many of these.) |
118+
| `501` | If Segment sends you an [API call type](https://segment.com/docs/connections/spec/#api-calls) (indicated by the `type` property included on all messages) you don't support, reply with this code. Read more about the API call types Segment supports [here](https://segment.com/docs/connections/spec/#api-calls). |
119+
| `503` | Send Segment this code when your endpoint is temporarily down for maintenance or otherwise not accepting messages. This helps Segment avoid dropping users' messages during your downtime. |
120+
121+
#### Response body
122+
123+
You can normally send back an empty body, but when sending back a `4xx`- or `5xx`-class error, you can optionally send Segment a diagnostic message that explains the error. This message is displayed to the user in the Segment debugger, and is be used in Segment's Event Delivery summaries.
124+
125+
Be sure to send JSON (and set your `Content-Type` header to `application/json`), and send your message in the `message` property.
126+
127+
Here's an example of a `401` response that helps a user track down why their calls aren't appearing in your tool's UI:
128+
129+
```json
130+
{
131+
"message": "API token expired"
132+
}
133+
```
134+
135+
Or, if your tool requires an email address in order to accept calls, use this example `400` reply:
136+
137+
```json
138+
{
139+
"message": "Missing email address"
140+
}
141+
```
142+
143+
## Test
144+
145+
When testing your integration, proceed through two separate flows:
146+
1. Test that your endpoint successfully ingests data in the way you would expect.
147+
2. Mimic a user implementing your integration within their Segment workspace.
148+
149+
### Your endpoint
150+
151+
Test your code directly from the Developer Portal UI. Use the `Send Test Events` tab and review the test events to make sure your destination works as expected.
152+
153+
154+
In the debugger panel, check the two outputs. The **Request from Segment** and the **Response from destination**.
155+
156+
* **Request from Segment** - What Segment posted to your endpoint
157+
* **Response from destination** - How your server responded
158+
159+
### The user flow
160+
161+
The ultimate goal is for Partners like yourself to create and publish high quality Destinations in [the Segment Catalog](https://segment.com/catalog/). Your Segment account doubles as a sandbox account to test your destination while you are still in a private "building" state.
162+
163+
To test your Destination in the Catalog, click the "View in workspace" button in the "Test in your workspace" section. This redirects to you a URL like https://app.segment.com/WORKSPACE-SLUG/destinations/catalog/APP-SLUG, which is your catalog entry.
164+
165+
From here, click "Configure App", select a Source, and click "Confirm Source". You can now configure your destination by setting the "API Key", then clicking the toggle to enable the destination.
166+
167+
Next you can click the "Event Tester" tab to send data to your destination. Here you can see what requests Segment sends to your destination and introspect the response you are returning. Learn more about the event tester [here](/docs/guides/best-practices/how-do-I-test-my-connections/).
168+
169+
Now you can use the JavaScript SDK in a browser to generate real analytics events.
170+
171+
Finally you should verify the data in your service.

0 commit comments

Comments
 (0)