Skip to content
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
29 changes: 29 additions & 0 deletions .changeset/auto-generated-sdk.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
"scope3": major
---

Generate SDK from OpenAPI specifications

Major refactor to automatically generate TypeScript SDK from OpenAPI specs:

**New Features:**
- Separate `PlatformClient` and `PartnerClient` for different user types
- Full code generation from OpenAPI YAML files (platform-api, partner-api, outcome-agent)
- Automated schema updates from agentic-api repository with GitHub Actions
- Custom SDK generator script that creates MCP-compatible resource classes

**Breaking Changes:**
- Removed manual resource files (now auto-generated)
- Removed SimpleMediaAgent (not in use)
- `Scope3AgenticClient` now extends `PlatformClient` (backwards compatible)

**Infrastructure:**
- Added `scripts/generate-sdk.ts` for SDK generation
- Added `scripts/update-schemas.sh` for automated OpenAPI spec updates
- GitHub workflow for daily automated type updates and PR creation
- Updated build process to use generated types

**Testing:**
- All 84 tests passing
- Verified with real API calls to production environment
- Both PlatformClient and PartnerClient confirmed working
28 changes: 28 additions & 0 deletions .changeset/remove-legacy-client.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
---
"scope3": major
---

BREAKING CHANGE: Remove legacy Scope3AgenticClient

The legacy `Scope3AgenticClient` class has been completely removed. Users must now explicitly choose between:

- `PlatformClient` - for brand advertisers/buyers managing campaigns and creatives
- `PartnerClient` - for DSPs/publishers/partners managing media buys and products

**Migration Guide:**

```typescript
// Before:
import { Scope3AgenticClient } from 'scope3';
const client = new Scope3AgenticClient({ apiKey: '...' });

// After (for brand advertisers):
import { PlatformClient } from 'scope3';
const client = new PlatformClient({ apiKey: '...' });

// After (for media partners):
import { PartnerClient } from 'scope3';
const client = new PartnerClient({ apiKey: '...' });
```

Both clients have the same configuration options and provide access to the appropriate API resources for their use case.
1 change: 1 addition & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
{
"root": true,
"parser": "@typescript-eslint/parser",
"extends": [
"eslint:recommended",
Expand Down
2 changes: 2 additions & 0 deletions .github/workflows/auto-update.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@ jobs:

- name: Fetch latest OpenAPI schemas
run: npm run update-schemas
env:
GITHUB_TOKEN: ${{ secrets.AGENTIC_API_TOKEN || secrets.PAT_TOKEN || secrets.GITHUB_TOKEN }}

- name: Check for changes
id: git-check
Expand Down
181 changes: 102 additions & 79 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,27 +23,64 @@ npm install scope3

## Quick Start

The SDK provides two separate clients for different use cases:

### PlatformClient (for Brand Advertisers/Buyers)

Use this client if you're a brand advertiser managing campaigns, creatives, and discovering media products.

```typescript
import { Scope3AgenticClient } from 'scope3';
import { PlatformClient } from 'scope3';

const client = new Scope3AgenticClient({
const platform = new PlatformClient({
apiKey: process.env.SCOPE3_API_KEY,
// Optional: specify environment (defaults to 'production')
environment: 'production', // or 'staging'
});

// List brand agents
const brandAgents = await client.brandAgents.list();
const brandAgents = await platform.brandAgents.list();

// Create a campaign
const campaign = await client.campaigns.create({
const campaign = await platform.campaigns.create({
prompt: 'Create a video campaign targeting tech enthusiasts',
budget: {
amount: 5000000, // $50,000 in cents
currency: 'USD',
pacing: 'even',
},
brandAgentId: '123',
});

// Discover media products
const products = await platform.mediaProducts.discover({
channels: ['DIGITAL-DISPLAY'],
budget: { min: 10000, max: 50000 },
});
```

### PartnerClient (for DSPs/Publishers/Sales Agents)

Use this client if you're a media partner managing tactics, media buys, and products.

```typescript
import { PartnerClient } from 'scope3';

const partner = new PartnerClient({
apiKey: process.env.SCOPE3_API_KEY,
environment: 'production', // or 'staging'
});

// Register a sales agent
const agent = await partner.agents.register({
name: 'My DSP',
type: 'SALES',
endpointUrl: 'https://my-dsp.com/mcp',
});

// Create a media buy
const mediaBuy = await partner.mediaBuys.create({
tacticId: 'tactic_123',
name: 'Q1 Campaign Buy',
budget: { amount: 100000, currency: 'USD' },
});

// Execute media buy
await partner.mediaBuys.execute({ mediaBuyId: mediaBuy.id });
```

## CLI Usage
Expand Down Expand Up @@ -90,8 +127,10 @@ scope3 --environment staging campaign list

## SDK Configuration

Both `PlatformClient` and `PartnerClient` accept the same configuration options:

```typescript
const client = new Scope3AgenticClient({
const client = new PlatformClient({
apiKey: 'your-api-key',

// Option 1: Use environment (recommended)
Expand All @@ -102,6 +141,7 @@ const client = new Scope3AgenticClient({

// Optional settings
timeout: 30000, // request timeout in ms
debug: false, // enable debug logging
});
```

Expand All @@ -112,95 +152,78 @@ const client = new Scope3AgenticClient({

## API Resources

The client provides access to all Scope3 API resources:

### Assets
```typescript
await client.assets.upload({ brandAgentId, assets: [...] });
await client.assets.list({ brandAgentId });
```

### Brand Agents
```typescript
await client.brandAgents.list();
await client.brandAgents.create({ name: 'My Brand' });
await client.brandAgents.get({ brandAgentId });
await client.brandAgents.update({ brandAgentId, name: 'Updated Name' });
await client.brandAgents.delete({ brandAgentId });
```
### PlatformClient Resources

### Campaigns
```typescript
await client.campaigns.list({ status: 'ACTIVE' });
await client.campaigns.create({ prompt: '...', budget: {...} });
await client.campaigns.update({ campaignId, status: 'PAUSED' });
await client.campaigns.getSummary({ campaignId });
await client.campaigns.listTactics({ campaignId });
await client.campaigns.delete({ campaignId });
// Assets
await platform.assets.upload({ brandAgentId, assets: [...] });
await platform.assets.list({ brandAgentId });

// Brand Agents
await platform.brandAgents.list();
await platform.brandAgents.create({ name: 'My Brand' });
await platform.brandAgents.get({ brandAgentId });
await platform.brandAgents.update({ brandAgentId, name: 'Updated Name' });
await platform.brandAgents.delete({ brandAgentId });

// Campaigns
await platform.campaigns.list({ status: 'ACTIVE' });
await platform.campaigns.create({ prompt: '...', budget: {...} });
await platform.campaigns.update({ campaignId, status: 'PAUSED' });
await platform.campaigns.getSummary({ campaignId });
await platform.campaigns.listTactics({ campaignId });
await platform.campaigns.delete({ campaignId });

// Creatives
await platform.creatives.list({ brandAgentId });
await platform.creatives.create({ brandAgentId, name: '...' });
await platform.creatives.assign({ creativeId, campaignId });

// Tactics
await platform.tactics.list({ campaignId });
await platform.tactics.create({ name: '...', campaignId });
await platform.tactics.update({ tacticId, channelCodes: ['DIGITAL-AUDIO'] });

// Other Resources
// - platform.brandStandards - Brand safety standards
// - platform.brandStories - AI-powered audience definitions
// - platform.channels - Advertising channels
// - platform.mediaProducts - Media product discovery
// - platform.targeting - Geographic and demographic targeting
```

### Creatives
```typescript
await client.creatives.list({ brandAgentId });
await client.creatives.create({ brandAgentId, name: '...' });
await client.creatives.assign({ creativeId, campaignId });
```
### PartnerClient Resources

### Tactics
```typescript
await client.tactics.list({ campaignId });
await client.tactics.create({ name: '...', campaignId });
await client.tactics.update({ tacticId, channelCodes: ['DIGITAL-AUDIO'] });
```

### Media Buys
```typescript
await client.mediaBuys.list({ tacticId });
await client.mediaBuys.create({
// Media Buys
await partner.mediaBuys.list({ tacticId });
await partner.mediaBuys.create({
tacticId,
name: '...',
products: [{ mediaProductId, salesAgentId }],
budget: { amount: 1000000 },
});
await client.mediaBuys.execute({ mediaBuyId });
```

### Agents
```typescript
// List all agents (sales and outcome)
await client.agents.list();
await client.agents.list({ type: 'SALES' });
await client.agents.list({ type: 'OUTCOME' });
await partner.mediaBuys.execute({ mediaBuyId });

// Register a new agent
await client.agents.register({
// Agents (Sales & Outcome)
await partner.agents.list();
await partner.agents.list({ type: 'SALES' });
await partner.agents.register({
type: 'SALES',
name: '...',
endpointUrl: '...',
protocol: 'MCP',
authenticationType: 'API_KEY',
});
await partner.agents.get({ agentId: '...' });
await partner.agents.update({ agentId: '...', name: 'Updated Name' });
await partner.agents.unregister({ agentId: '...' });

// Get agent details
await client.agents.get({ agentId: '...' });

// Update agent
await client.agents.update({
agentId: '...',
name: 'Updated Name',
});

// Unregister agent
await client.agents.unregister({ agentId: '...' });
// Other Resources
// - partner.products - Media product management
// - partner.webhooks - Webhook configuration
```

### Other Resources
- `client.brandStandards` - Brand safety standards
- `client.brandStories` - AI-powered audience definitions
- `client.channels` - Advertising channels
- `client.notifications` - System notifications
- `client.products` - Media product management

## Webhook Server

The client includes an optional webhook server for handling AdCP events:
Expand Down
4 changes: 2 additions & 2 deletions examples/basic-usage.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Scope3AgenticClient } from '../src';
import { PlatformClient } from '../src';

async function main() {
const client = new Scope3AgenticClient({
const client = new PlatformClient({
apiKey: process.env.SCOPE3_API_KEY || 'your-api-key',
});

Expand Down
4 changes: 2 additions & 2 deletions examples/create-campaign.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Scope3AgenticClient } from '../src';
import { PlatformClient } from '../src';

async function main() {
const client = new Scope3AgenticClient({
const client = new PlatformClient({
apiKey: process.env.SCOPE3_API_KEY || 'your-api-key',
});

Expand Down
Loading