Skip to content

feat: docs sdk page #386

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 16, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 125 additions & 0 deletions docs/pages/sdks.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
---
title: SDKs
description: An overview of the Outpost SDKs for Go, TypeScript, and Python.
---

Outpost provides Software Development Kits (SDKs) to help you integrate your applications with the Outpost API seamlessly. These SDKs are designed to simplify the process of publishing events and managing your Outpost resources.

The SDKs are generated from the <a href="./apis/openapi.yaml">Outpost OpenAPI specification</a> using [Speakeasy](https://speakeasy.com).

## Available SDKs

We currently offer SDKs for the following languages:

- **[TypeScript/JavaScript](https://github.com/hookdeck/outpost/tree/main/sdks/outpost-typescript)**
- **[Go](https://github.com/hookdeck/outpost/tree/main/sdks/outpost-go)**
- **[Python](https://github.com/hookdeck/outpost/tree/main/sdks/outpost-python)**

Each SDK provides a convenient way to interact with the Outpost API, including publishing events, managing topics, and configuring destinations.

## Usage Example (TypeScript)

Here's an example of how you might use the TypeScript SDK to:

1. Create an `Outpost` instance using an Admin API Key.
2. Create a new tenant.
3. Create a destination for that tenant.
4. Publish an event for the created tenant.

You can find the code for this in [`examples/sdk-typescript/index.ts`](https://github.com/hookdeck/outpost/tree/main/examples/sdk-typescript/index.ts).

Begin by installing the TypeScript SDK:

```bash
npm install @hookdeck/outpost-sdk
```

Then, create a file named `index.ts` and add the following code:

```typescript
import { randomUUID } from "crypto";
import dotenv from "dotenv";
dotenv.config();
import { Outpost } from "@hookdeck/outpost-sdk";

const ADMIN_API_KEY = process.env.ADMIN_API_KEY;
const SERVER_URL = process.env.OUTPOST_URL || "http://localhost:3333";

if (!ADMIN_API_KEY) {
console.error("Please set the ADMIN_API_KEY environment variable.");
process.exit(1);
}

async function manageOutpostResources() {
// 1. Create an Outpost instance using the AdminAPIKey
const outpostAdmin = new Outpost({
security: { adminApiKey: ADMIN_API_KEY },
serverURL: `${SERVER_URL}/api/v1`,
});

const tenantId = `hookdeck`;
const topic = `user.created`;
const newDestinationName = `My Test Destination ${randomUUID()}`;

try {
// 2. Create a tenant
console.log(`Creating tenant: ${tenantId}`);
const tenant = await outpostAdmin.tenants.upsert({
tenantId,
});
console.log("Tenant created successfully:", tenant);

// 3. Create a destination for the tenant
console.log(
`Creating destination: ${newDestinationName} for tenant ${tenantId}...`
);
const destination = await outpostAdmin.destinations.create({
tenantId,
destinationCreate: {
type: "webhook",
config: {
url: "https://example.com/webhook-receiver",
},
topics: [topic],
},
});
console.log("Destination created successfully:", destination);

// 4. Publish an event for the created tenant
const eventPayload = {
userId: "user_456",
orderId: "order_xyz",
timestamp: new Date().toISOString(),
};

console.log(`Publishing event to topic ${topic} for tenant ${tenantId}...`);
await outpostAdmin.publish.event({
data: eventPayload,
tenantId,
topic,
eligibleForRetry: true,
});

console.log("Event published successfully");
} catch (error) {
console.error("An error occurred:", error);
}
}

manageOutpostResources();
```

For detailed instructions, API references, and more advanced usage examples, please refer to the README file within each SDK's directory on GitHub.

## Getting Started

To get started with an SDK:

1. Navigate to the respective SDK directory on GitHub:
- [TypeScript SDK](https://github.com/hookdeck/outpost/tree/main/sdks/outpost-typescript)
- [Go SDK](https://github.com/hookdeck/outpost/tree/main/sdks/outpost-go)
- [Python SDK](https://github.com/hookdeck/outpost/tree/main/sdks/outpost-python)
2. Follow the installation and usage instructions provided in the SDK's `README.md` file and the documenation within the SDK repository.
3. Ensure your Outpost instance is running and accessible, and that you have the necessary API keys and configuration.

If you have any questions or encounter issues, please feel free to open an issue on our [GitHub repository](https://github.com/hookdeck/outpost/issues).
5 changes: 5 additions & 0 deletions docs/zudoku.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,11 @@ const config: ZudokuConfig = {
{ type: "doc", id: "features/tenant-user-portal" },
{ type: "doc", id: "features/opentelemetry" },
{ type: "doc", id: "features/logging" },
{
type: "doc",
label: "SDKs",
id: "sdks",
},
],
},
{
Expand Down
110 changes: 110 additions & 0 deletions examples/sdk-typescript/auth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { randomUUID } from "crypto";
import dotenv from "dotenv";
dotenv.config();
import { Outpost } from "@hookdeck/outpost-sdk";

const TENANT_ID = process.env.TENANT_ID;
const ADMIN_API_KEY = process.env.ADMIN_API_KEY;
const SERVER_URL = process.env.SERVER_URL;

if (!process.env.ADMIN_API_KEY) {
console.error("Please set the ADMIN_API_KEY environment variable.");
process.exit(1);
}
if (!process.env.SERVER_URL) {
console.error("Please set the SERVER_URL environment variable.");
process.exit(1);
}
if (!process.env.TENANT_ID ) {
console.error("Please set the TENANT_ID environment variable.");
process.exit(1);
}

const debugLogger = {
debug: (message: string) => {
console.log("DEBUG", message);
},
group: (message: string) => {
console.group(message);
},
groupEnd: () => {
console.groupEnd();
},
log: (message: string) => {
console.log(message);
}
};

const withJwt = async (jwt: string) => {
const outpost = new Outpost({security: {tenantJwt: jwt}, serverURL: `${SERVER_URL}/api/v1`, tenantId: TENANT_ID });
const destinations = await outpost.destinations.list({});

console.log(destinations);
}

const withAdminApiKey = async () => {
const outpost = new Outpost({security: {adminApiKey: ADMIN_API_KEY}, serverURL: `${SERVER_URL}/api/v1`});

const result = await outpost.health.check();
console.log(result);

const tenantId = `hookdeck`;
const topic = `user.created`;
const newDestinationName = `My Test Destination ${randomUUID()}`;

console.log(`Creating tenant: ${tenantId}`);
const tenant = await outpost.tenants.upsert({
tenantId: tenantId,
});
console.log("Tenant created successfully:", tenant);

console.log(
`Creating destination: ${newDestinationName} for tenant ${tenantId}...`
);
const destination = await outpost.destinations.create({
tenantId,
destinationCreate: {
type: "webhook",
config: {
url: "https://example.com/webhook-receiver",
},
topics: ["user.created"],
}
});
console.log("Destination created successfully:", destination);

const eventPayload = {
userId: "user_456",
orderId: "order_xyz",
timestamp: new Date().toISOString(),
};

console.log(
`Publishing event to topic ${topic} for tenant ${tenantId}...`
);
await outpost.publish.event({
data: eventPayload,
tenantId,
topic: "user.created",
eligibleForRetry: true,
});

console.log("Event published successfully");

const destinations = await outpost.destinations.list({tenantId: TENANT_ID})

console.log(destinations);

const jwt = await outpost.tenants.getToken({tenantId: TENANT_ID});

await withJwt(jwt.token!);
}

const main = async () => {
await withAdminApiKey();
}

main().catch((e) => {
console.error(e);
process.exit(1);
});
100 changes: 52 additions & 48 deletions examples/sdk-typescript/index.ts
Original file line number Diff line number Diff line change
@@ -1,66 +1,70 @@
import { randomUUID } from "crypto";
import dotenv from "dotenv";
dotenv.config();
import { Outpost } from "@hookdeck/outpost-sdk";

const TENANT_ID = process.env.TENANT_ID;
const ADMIN_API_KEY = process.env.ADMIN_API_KEY;
const SERVER_URL = process.env.SERVER_URL;
const SERVER_URL = process.env.OUTPOST_URL || "http://localhost:3333";

if (!process.env.ADMIN_API_KEY) {
if (!ADMIN_API_KEY) {
console.error("Please set the ADMIN_API_KEY environment variable.");
process.exit(1);
}
if (!process.env.SERVER_URL) {
console.error("Please set the SERVER_URL environment variable.");
process.exit(1);
}
if (!process.env.TENANT_ID ) {
console.error("Please set the TENANT_ID environment variable.");
process.exit(1);
}

const debugLogger = {
debug: (message: string) => {
console.log("DEBUG", message);
},
group: (message: string) => {
console.group(message);
},
groupEnd: () => {
console.groupEnd();
},
log: (message: string) => {
console.log(message);
}
};

const withJwt = async (jwt: string) => {
const outpost = new Outpost({security: {tenantJwt: jwt}, serverURL: `${SERVER_URL}/api/v1`, tenantId: TENANT_ID });
const destinations = await outpost.destinations.list({});
async function manageOutpostResources() {
// 1. Create an Outpost instance using the AdminAPIKey
const outpostAdmin = new Outpost({
security: { adminApiKey: ADMIN_API_KEY },
serverURL: `${SERVER_URL}/api/v1`,
});

console.log(destinations);
}

const withAdminApiKey = async () => {
const outpost = new Outpost({security: {adminApiKey: ADMIN_API_KEY}, serverURL: `${SERVER_URL}/api/v1`});

const result = await outpost.health.check();
console.log(result);
const tenantId = `hookdeck`;
const topic = `user.created`;
const newDestinationName = `My Test Destination ${randomUUID()}`;

const destinations = await outpost.destinations.list({tenantId: TENANT_ID})
try {
// 2. Create a tenant
console.log(`Creating tenant: ${tenantId}`);
const tenant = await outpostAdmin.tenants.upsert({
tenantId,
});
console.log("Tenant created successfully:", tenant);

console.log(destinations);
// 3. Create a destination for the tenant
console.log(
`Creating destination: ${newDestinationName} for tenant ${tenantId}...`
);
const destination = await outpostAdmin.destinations.create({
tenantId,
destinationCreate: {
type: "webhook",
config: {
url: "https://example.com/webhook-receiver",
},
topics: [topic],
},
});
console.log("Destination created successfully:", destination);

const jwt = await outpost.tenants.getToken({tenantId: TENANT_ID});
// 4. Publish an event for the created tenant
const eventPayload = {
userId: "user_456",
orderId: "order_xyz",
timestamp: new Date().toISOString(),
};

await withJwt(jwt.token!);
}
console.log(`Publishing event to topic ${topic} for tenant ${tenantId}...`);
await outpostAdmin.publish.event({
data: eventPayload,
tenantId,
topic,
eligibleForRetry: true,
});

const main = async () => {
await withAdminApiKey();
console.log("Event published successfully");
} catch (error) {
console.error("An error occurred:", error);
}
}

main().catch((e) => {
console.error(e);
process.exit(1);
});
manageOutpostResources();
3 changes: 2 additions & 1 deletion examples/sdk-typescript/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
"typescript": "^5.8.3"
},
"scripts": {
"start": "node --loader ts-node/esm index.ts"
"start": "node --loader ts-node/esm index.ts",
"auth": "node --loader ts-node/esm auth.ts"
}
}
2 changes: 1 addition & 1 deletion examples/sdk-typescript/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,5 @@
"strict": true,
"skipLibCheck": true
},
"include": ["index.ts"]
"include": ["*.ts"],
Copy link
Preview

Copilot AI May 15, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ensure that the new include pattern ('*.ts') in tsconfig.json covers the intended files and does not unintentionally include test or support files.

Suggested change
"include": ["*.ts"],
"include": ["src/**/*.ts"],
"exclude": ["**/*.test.ts", "**/*.d.ts"],

Copilot uses AI. Check for mistakes.

}