Skip to main content

Overview

This reference describes the protocol your outcome agent server must implement. These are endpoints that YOU implement on YOUR infrastructure, and Scope3’s platform will call them.

Download OpenAPI Spec

Download the complete OpenAPI specification for the Outcome Agent Protocol

Authentication

Your outcome agent server must authenticate requests from Scope3. When registering your agent, specify which authentication type you support: Scope3 sends requests with an API key in the header:
X-API-Key: your-secret-key

Bearer Token (OAuth)

For OAuth-based authentication:
Authorization: Bearer jwt-token

Basic Auth

Username/password authentication:
Authorization: Basic base64(username:password)

Base URL

Your outcome agent server runs at your own domain:
https://outcome-agent.yourcompany.com
This is the URL you provide when registering with Scope3.

Endpoints You Must Implement

POST /get-proposed-tactics

Called by Scope3 when: Setting up a new campaign Scope3 calls this to ask what tactics your agent can handle. Analyze the campaign and respond with proposed tactics, budget capacity, and pricing.
app.post('/get-proposed-tactics', async (req, res) => {
  const { campaignId, budgetRange, channels, seatId } = req.body;

  // Analyze if we can handle this campaign
  const canHandle = await analyzeCampaign({ channels, budgetRange });

  if (!canHandle) {
    return res.json({ proposedTactics: [] });
  }

  // Propose tactics
  res.json({
    proposedTactics: [
      {
        tacticId: "premium-vcpm-display",
        execution: "Target premium inventory at $2.50 vCPM with 85% viewability",
        budgetCapacity: 50000,
        pricing: {
          method: "vcpm",
          rate: 2.50,
          currency: "USD"
        },
        sku: "premium-vcpm",
        customFieldsRequired: [
          {
            fieldName: "targetVCPM",
            fieldType: "number",
            description: "Target vCPM in USD"
          }
        ]
      }
    ]
  });
});
Request Body (from Scope3)
FieldTypeDescription
campaignIdstringCampaign ID
budgetRangeobjectBudget range (buyer won’t reveal full budget)
budgetRange.minnumberMinimum budget
budgetRange.maxnumberMaximum budget
budgetRange.currencystringCurrency (ISO 4217 code, defaults to USD)
startDatestringCampaign start date in UTC (ISO 8601)
endDatestringCampaign end date in UTC (ISO 8601)
channelsarrayChannels: display, video, audio, native, ctv (ADCP aligned)
countriesarrayISO 3166-1 alpha-2 country codes
objectivesarrayCampaign objectives/outcomes
briefstringCampaign brief text
acceptedPricingMethodsarrayPricing methods buyer accepts: cpm, vcpm, cpc, cpa, cpv, flat_fee, revshare
promotedOfferingsarraySpecific offerings buyer is interested in
seatIdstringSeat/account ID
Your Response
FieldTypeRequiredDescription
proposedTacticsarrayYesList of tactics you can handle
proposedTactics[].tacticIdstringYesUnique ID (you generate this)
proposedTactics[].executionstringYesHow you’ll execute this tactic
proposedTactics[].budgetCapacitynumberYesMax budget you can handle
proposedTactics[].pricingobjectYesYour pricing model
proposedTactics[].pricing.methodstringYesPricing method: cpm, vcpm, cpc, cpa, cpv, flat_fee, revshare
proposedTactics[].pricing.ratenumberYesRate (e.g., CPM in USD, percentage for revshare)
proposedTactics[].pricing.currencystringNoCurrency (ISO 4217 code, defaults to USD)
proposedTactics[].skustringNoIdentifier for this tactic type
proposedTactics[].customFieldsRequiredarrayNoCustom fields needed from advertiser

POST /accept-proposal

Called by Scope3 when: Your proposal is accepted and you are assigned to manage a tactic Your agent should acknowledge and begin managing the tactic, or decline if unable to fulfill.
app.post('/accept-proposal', async (req, res) => {
  const { tacticId, proposalId, tacticContext, customFields, proposal_context } = req.body;

  try:
    // Set up tactic management
    await setupTactic(tacticId, proposalId, tacticContext, customFields, proposal_context);

    // Acknowledge
    res.json({ acknowledged: true });

    // Start optimization (async)
    optimizeTactic(tacticId).catch(console.error);
  } catch (error) {
    res.json({
      acknowledged: false,
      reason: error.message
    });
  }
});
Request Body (from Scope3)
FieldTypeDescription
tacticIdstringID of the tactic from the strategy table (assigned when user accepts your proposal)
proposalIdstringID of the proposal that was accepted (matches proposalId from your response)
tacticContextobjectComplete tactic details
tacticContext.budgetnumberBudget allocated
tacticContext.budgetCurrencystringCurrency (ISO 4217 code, defaults to USD)
tacticContext.startDatestringCampaign start date in UTC (ISO 8601)
tacticContext.endDatestringCampaign end date in UTC (ISO 8601)
tacticContext.channelstringAdvertising channel
tacticContext.countriesarrayTarget countries
tacticContext.creativesarrayCreative assets
tacticContext.brandStandardsobjectBrand safety rules (Scope3 handles)
brandAgentIdstringBrand agent ID
seatIdstringSeat/account ID
customFieldsobjectCustom fields from advertiser
proposal_contextobjectThe proposal_context data you returned in your original proposal response
Your Response
FieldTypeRequiredDescription
acknowledgedbooleanYestrue to accept, false to decline
reasonstringNoReason if declining

POST /tactic-context-updated

Called by Scope3 when: Tactic is modified (budget, schedule, etc.) Your agent MUST handle these changes as they may impact delivery.
app.post('/tactic-context-updated', async (req, res) => {
  const { tacticId, tactic, patch } = req.body;

  // Update tactic configuration based on changes
  await updateTacticConfig(tacticId, patch);

  res.status(200).send();
});
Request Body (from Scope3)
FieldTypeDescription
tacticIdstringTactic ID
tacticobjectCurrent tactic state (after changes)
patcharrayJSON Patch (RFC 6902) changes
Patch Format Example
[
  {
    "op": "replace",
    "path": "/budget",
    "value": 60000
  }
]
Your Response Return 200 OK to acknowledge.

POST /tactic-creatives-updated

Called by Scope3 when: Creatives are added, removed, or modified Update your media buys to use the new creative assets.
app.post('/tactic-creatives-updated', async (req, res) => {
  const { tacticId, tactic, patch } = req.body;

  // Update creatives in media buys
  await updateCreatives(tacticId, patch);

  res.status(200).send();
});
Request Body (from Scope3)
FieldTypeDescription
tacticIdstringTactic ID
tacticobjectCurrent tactic with updated creatives
patcharrayJSON Patch changes to creatives
Your Response Return 200 OK.

POST /tactic-feedback

Called by Scope3 when: Sending performance feedback Your agent MAY use this to optimize delivery.
app.post('/tactic-feedback', async (req, res) => {
  const { tacticId, deliveryIndex, performanceIndex } = req.body;

  // Optimize based on feedback
  if (deliveryIndex < 90) {
    await increaseBudgetAllocation(tacticId);
  }

  if (performanceIndex > 120) {
    await scaleWinningProducts(tacticId);
  }

  res.status(200).send();
});
Request Body (from Scope3)
FieldTypeDescription
tacticIdstringTactic ID
startDatestringFeedback interval start in UTC (ISO 8601)
endDatestringFeedback interval end in UTC (ISO 8601)
deliveryIndexnumber100 = on target, <100 = under-delivering, >100 = over-delivering
performanceIndexnumber100 = maximum, relative to target or other tactics
Your Response Return 200 OK.

Using Scope3’s Platform APIs

Once managing a tactic, your agent calls Scope3’s platform APIs to execute media buys.

Get Sales Agent Products

curl https://api.agentic.scope3.com/rest/v1/get-products \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "channels": ["display"],
    "countries": ["US"]
  }'

Create Media Buy

curl https://api.agentic.scope3.com/rest/v1/create-media-buy \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "tacticId": "premium-vcpm-display",
    "productId": "prod_456",
    "budget": 10000
  }'

Update Tactic Targeting

curl https://api.agentic.scope3.com/rest/v1/update-targeting \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -d '{
    "tacticId": "premium-vcpm-display",
    "segments": ["premium-auto-enthusiasts"],
    "frequencyCap": {
      "impressions": 5,
      "period": "day"
    }
  }'
See the main API Reference for complete documentation of Scope3’s platform APIs.

Registering Your Outcome Agent

Once your server is running, register with Scope3:
curl -X POST https://api.agentic.scope3.com/rest/v1/outcome-agent-register \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "vCPM Optimizer Pro",
    "description": "Optimizes for lowest vCPM with high viewability",
    "endpointUrl": "https://media-agent.yourcompany.com",
    "authenticationType": "API_KEY",
    "apiKey": "your-secret-key-for-scope3-to-use",
    "supportedChannels": ["display", "video"],
    "supportedCountries": ["US", "CA", "GB"]
  }'
Registration Fields
FieldTypeRequiredDescription
namestringYesDisplay name for your agent
descriptionstringYesWhat your agent does
endpointUrlstringYesBase URL of your server
authenticationTypestringYesAPI_KEY, BEARER_TOKEN, or BASIC_AUTH
apiKeystringConditionalRequired if using API_KEY auth
bearerTokenstringConditionalRequired if using BEARER_TOKEN auth
username / passwordstringConditionalRequired if using BASIC_AUTH
supportedChannelsarrayYesChannels you support
supportedCountriesarrayYesCountries you support

Best Practices

Endpoint Reliability

  • Respond within 10 seconds
  • Use proper HTTP status codes (200, 400, 500)
  • Implement idempotency for all operations
  • Log all requests for debugging

Error Handling

  • Return 200 with acknowledged: false to decline tactics gracefully
  • Provide clear error messages in reason field
  • Don’t return 5xx errors for business logic failures

Security

  • Validate authentication on all requests
  • Use HTTPS only
  • Rotate API keys regularly
  • Rate limit to prevent abuse

Performance

  • Process requests asynchronously when possible
  • Use background jobs for optimization
  • Cache frequently accessed data
  • Monitor endpoint latency

Testing Your Implementation

Use Scope3’s staging environment to test your outcome agent:
  1. Register with staging: https://api.agentic.staging.scope3.com
  2. Test each endpoint with sample payloads
  3. Verify authentication works correctly
  4. Monitor logs for errors
  5. Validate responses match the protocol spec
Contact your Scope3 account manager for staging access.

Support