Skip to main content
Learn how to integrate with the Yuno Campaigns API to automate personalized communications for declined payment recovery.

Endpoints

Base URL: https://api-sandbox.y.uno/v1

Overview

The Campaigns API allows you to create automated communication campaigns that are triggered when a customer’s payment is declined. When a payment event matches your campaign’s targeting rules, Yuno automatically sends a personalized message to the customer through the configured channel (WhatsApp or phone call), helping recover the failed transaction.

Key concepts

  • Campaign: Defines who to target, through which channel, and when to send communications.
  • Rules: Conditions attached to a campaign that determine which declined payments qualify. All active rules must pass for a payment to trigger the campaign (AND logic).
  • Schedule: Controls the daily time window and timezone for sending communications.
  • Duration: The start and end dates during which the campaign is active.

How it works

Example: You create a campaign targeting declined payments in Colombia with amounts over 50,000 COP. When a Colombian customer’s 80,000 COP payment is declined, Yuno automatically sends them a WhatsApp message with a personalized recovery suggestion.

Authentication

All API requests require the following headers:
HeaderDescriptionRequired
X-Public-Api-KeyYour merchant public API keyYes
X-Private-Secret-KeyYour merchant private secret keyYes
Content-TypeMust be application/json for POST/PATCH requestsYes
curl -X GET https://api-sandbox.y.uno/v1/campaigns \
  -H "X-Public-Api-Key: your-public-api-key" \
  -H "X-Private-Secret-Key: your-private-secret-key"

Data models

Campaign object

FieldTypeDescription
idUUIDUnique campaign identifier
namestringCampaign name
account_idUUIDYuno account ID
organization_codeUUIDOrganization identifier
countrystringISO 3166-1 alpha-2 country code
channelenumWHATSAPP_MESSAGE or PHONE_CALL
focusstringOptional campaign focus descriptor
scheduleobjectScheduling configuration
durationobjectCampaign active period
statusstringACTIVE, PAUSED, COMPLETED, or CANCELLED
rulesarrayRules attached to the campaign (included in GET by ID)
created_atstringISO 8601 creation timestamp
updated_atstringISO 8601 last update timestamp

Rule object

FieldTypeDescription
idUUIDUnique rule identifier
campaign_idUUIDID of the campaign this rule belongs to
rule_typestringType of rule (see reference below)
valuesarrayArray of string values for comparison
conditionalstringComparison operator (see reference below)
metadata_keystringMetadata field name (only for METADATA rules)
statusstringACTIVE or INACTIVE
created_atstringISO 8601 creation timestamp
updated_atstringISO 8601 last update timestamp

Rule types reference

Rules define which declined payments qualify for a campaign. All active rules on a campaign must pass (AND logic) for a communication to be triggered.

Payment data rules

These rules evaluate data directly available from the payment event.
Rule TypeDescriptionValues FormatExample
AMOUNTFilter by payment amount["number"]["50000"]
CURRENCYFilter by currency code["code"]["COP"]
AMOUNT_AND_CURRENCYCombined amount + currency check["amount", "currency"]["50000", "COP"]
PAYMENT_STATUSFilter by payment status["status"]["DECLINED"]

Enriched data rules

These rules evaluate enriched transaction data (payment method, provider, card details, etc.).
Rule TypeDescriptionValues FormatExample
PAYMENT_METHODFilter by payment method type["method"]["CARD"]
PROVIDERFilter by payment provider ID["provider_id"]["stripe"]
CARD_BINFilter by card BIN/IIN prefix["bin_prefix"]["411111", "552345"]
RESPONSE_CODEFilter by provider response code["code"]["05", "51"]
ISO_RESPONSE_CODEFilter by ISO 8583 response code["code"]["51", "05"]
CATEGORYFilter by transaction category["category"]["ecommerce"]

Metadata rules

Evaluate custom metadata fields attached to the payment.
Rule TypeDescriptionValues FormatRequires metadata_key
METADATAFilter by custom metadata key-value["value"]Yes
Example: Target payments from a specific business vertical:
{
  "rule_type": "METADATA",
  "metadata_key": "vertical",
  "values": ["restaurant", "grocery"],
  "conditional": "ONE_OF"
}

Rate limiting rules

Control communication frequency to avoid sending too many messages to the same user.
Rule TypeDescriptionValues FormatExample
USER_COMMS_PER_DAYMax communications per user per day["limit"]["3"]
UNIQUE_BY_USEROne communication per user per campaignNot applicable-
Important notes on rate limiting rules:
  • Both USER_COMMS_PER_DAY and UNIQUE_BY_USER require a user_id field to be present in the payment metadata.
  • USER_COMMS_PER_DAY does not require a conditional field. Only provide values with the daily limit.
  • UNIQUE_BY_USER requires neither values nor conditional. Simply include the rule_type.

Conditional operators reference

ConditionalDescriptionApplicable Rule TypesValues Count
EQUALExact matchAll1
NOT_EQUALDoes not matchAll1
ONE_OFMatches any value in listAll1+
NOT_ONE_OFMatches none of the valuesAll1+
INSame as ONE_OFAll1+
GREATER_THANGreater than (numeric)AMOUNT, AMOUNT_AND_CURRENCY, METADATA1
GREATER_THAN_OR_EQUALGreater than or equal (numeric)AMOUNT, AMOUNT_AND_CURRENCY, METADATA1
LESS_THANLess than (numeric)AMOUNT, AMOUNT_AND_CURRENCY, METADATA1
LESS_THAN_OR_EQUALLess than or equal (numeric)AMOUNT, AMOUNT_AND_CURRENCY, METADATA1
BETWEENBetween two values, inclusive (numeric)AMOUNT, AMOUNT_AND_CURRENCY, METADATA2 (or 3 for AMOUNT_AND_CURRENCY)
CONTAINSContains substring (case-insensitive)METADATA1+
STARTS_WITHStarts with prefixCARD_BIN, METADATA1+
Note on BETWEEN with AMOUNT_AND_CURRENCY: When using BETWEEN with AMOUNT_AND_CURRENCY, provide 3 values: ["min", "max", "currency"]. For other rule types, provide 2 values: ["min", "max"].

Getting started

Step 1: Create a campaign

Define who to target, which channel to use, and when communications should be sent.
curl -X POST https://api-sandbox.y.uno/v1/campaigns \
  -H "X-Public-Api-Key: your-public-api-key" \
  -H "X-Private-Secret-Key: your-private-secret-key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Declined Payment Recovery - Colombia",
    "account_id": "YOUR_ACCOUNT_ID",
    "organization_code": "YOUR_ORGANIZATION_CODE",
    "country": "CO",
    "channel": "WHATSAPP_MESSAGE",
    "schedule": {
      "daily_start_time": "08:00",
      "daily_end_time": "21:00",
      "time_zone": "America/Bogota"
    },
    "duration": {
      "start_at": "2025-07-01T00:00:00Z",
      "end_at": "2026-07-01T00:00:00Z"
    }
  }'
Note: The campaign is created with ACTIVE status by default. Save the returned id for the next step.

Step 2: Add targeting rules

Define which declined payments should trigger this campaign. Use the campaign id from Step 1.
curl -X POST https://api-sandbox.y.uno/v1/campaigns/{campaign_id}/rules \
  -H "X-Public-Api-Key: your-public-api-key" \
  -H "X-Private-Secret-Key: your-private-secret-key" \
  -H "Content-Type: application/json" \
  -d '{
    "rules": [
      {
        "rule_type": "PAYMENT_STATUS",
        "values": ["DECLINED"],
        "conditional": "EQUAL"
      },
      {
        "rule_type": "CURRENCY",
        "values": ["COP"],
        "conditional": "EQUAL"
      },
      {
        "rule_type": "AMOUNT",
        "values": ["50000"],
        "conditional": "GREATER_THAN"
      },
      {
        "rule_type": "USER_COMMS_PER_DAY",
        "values": ["2"]
      }
    ]
  }'
This campaign will now trigger a WhatsApp message when:
  • Payment status is DECLINED AND
  • Currency is COP AND
  • Amount is greater than 50,000 AND
  • The user has received fewer than 2 communications today

Step 3: Verify your campaign

Confirm the campaign is set up correctly with its rules.
curl -X GET https://api-sandbox.y.uno/v1/campaigns/{campaign_id} \
  -H "X-Public-Api-Key: your-public-api-key" \
  -H "X-Private-Secret-Key: your-private-secret-key"

Step 4: Monitor and manage

  • Pause a campaign temporarily: PATCH with {"status": "PAUSED"}
  • Resume a paused campaign: PATCH with {"status": "ACTIVE"}
  • Disable a specific rule without deleting it: PATCH /rules/{rule_id}/status with {"status": "INACTIVE"}
  • End a campaign permanently: PATCH with {"status": "COMPLETED"}

Use case examples

1. Basic declined payment recovery

Send a WhatsApp message to customers in Mexico whose card payments are declined. Campaign:
{
  "name": "Mexico Card Recovery",
  "account_id": "YOUR_ACCOUNT_ID",
  "organization_code": "YOUR_ORGANIZATION_CODE",
  "country": "MX",
  "channel": "WHATSAPP_MESSAGE",
  "focus": "payment_recovery",
  "schedule": {
    "daily_start_time": "09:00",
    "daily_end_time": "20:00",
    "time_zone": "America/Mexico_City"
  },
  "duration": {
    "start_at": "2025-08-01T00:00:00Z",
    "end_at": "2026-08-01T00:00:00Z"
  }
}
Rules:
{
  "rules": [
    {
      "rule_type": "PAYMENT_STATUS",
      "values": ["DECLINED"],
      "conditional": "EQUAL"
    },
    {
      "rule_type": "PAYMENT_METHOD",
      "values": ["CARD"],
      "conditional": "EQUAL"
    }
  ]
}

2. High-value transaction recovery via phone call

Call customers whose transactions above 500 USD were declined. Campaign:
{
  "name": "High Value Recovery - Phone",
  "account_id": "YOUR_ACCOUNT_ID",
  "organization_code": "YOUR_ORGANIZATION_CODE",
  "country": "CO",
  "channel": "PHONE_CALL",
  "focus": "payment_recovery",
  "schedule": {
    "daily_start_time": "09:00",
    "daily_end_time": "18:00",
    "time_zone": "America/Bogota"
  },
  "duration": {
    "start_at": "2025-08-01T00:00:00Z",
    "end_at": "2026-08-01T00:00:00Z"
  }
}
Rules:
{
  "rules": [
    {
      "rule_type": "PAYMENT_STATUS",
      "values": ["DECLINED"],
      "conditional": "EQUAL"
    },
    {
      "rule_type": "AMOUNT_AND_CURRENCY",
      "values": ["500", "USD"],
      "conditional": "GREATER_THAN"
    },
    {
      "rule_type": "USER_COMMS_PER_DAY",
      "values": ["1"]
    }
  ]
}

3. Provider-specific recovery with amount range

Target declined payments from a specific provider within an amount range. Rules:
{
  "rules": [
    {
      "rule_type": "PAYMENT_STATUS",
      "values": ["DECLINED"],
      "conditional": "EQUAL"
    },
    {
      "rule_type": "PROVIDER",
      "values": ["stripe", "adyen"],
      "conditional": "ONE_OF"
    },
    {
      "rule_type": "AMOUNT",
      "values": ["10000", "500000"],
      "conditional": "BETWEEN"
    },
    {
      "rule_type": "CURRENCY",
      "values": ["COP"],
      "conditional": "EQUAL"
    }
  ]
}

4. Metadata-based segmentation

Target specific customer segments using payment metadata (e.g., business vertical or customer tier). Rules:
{
  "rules": [
    {
      "rule_type": "PAYMENT_STATUS",
      "values": ["DECLINED"],
      "conditional": "EQUAL"
    },
    {
      "rule_type": "METADATA",
      "metadata_key": "vertical",
      "values": ["restaurant", "grocery"],
      "conditional": "ONE_OF"
    },
    {
      "rule_type": "METADATA",
      "metadata_key": "customer_tier",
      "values": ["premium", "gold"],
      "conditional": "ONE_OF"
    },
    {
      "rule_type": "UNIQUE_BY_USER"
    }
  ]
}

5. Exclude specific response codes

Send recovery messages for all declined payments except those with specific response codes that indicate fraud or permanent issues. Rules:
{
  "rules": [
    {
      "rule_type": "PAYMENT_STATUS",
      "values": ["DECLINED"],
      "conditional": "EQUAL"
    },
    {
      "rule_type": "ISO_RESPONSE_CODE",
      "values": ["14", "43", "59"],
      "conditional": "NOT_ONE_OF"
    }
  ]
}
Note: ISO codes 14 (invalid card number), 43 (stolen card), and 59 (suspected fraud) are excluded since these should not receive recovery communications.

Error handling

All error responses follow a consistent format:
{
  "code": 400,
  "message": "Descriptive error message",
  "details": "Additional context (optional)"
}

HTTP status codes

CodeDescriptionCommon Causes
400Bad RequestInvalid UUID, missing required fields, invalid query parameters
404Not FoundCampaign or rule does not exist
422Unprocessable EntityValidation failed (e.g., invalid rule type, invalid conditional for rule type, end_at before start_at)
500Internal Server ErrorUnexpected server error

Common validation errors

ErrorCauseSolution
Invalid campaign_idNon-UUID path parameterUse the UUID returned from campaign creation
Invalid rule_typeUnrecognized rule type valueSee Rule Types Reference
Invalid conditionalConditional not valid for rule typeSee Conditional Operators Reference
BETWEEN requires 2 valuesvalues array has wrong number of elementsProvide exactly 2 values: ["min", "max"] (or 3 for AMOUNT_AND_CURRENCY: ["min", "max", "currency"])
metadata_key requiredMETADATA rule without metadata_keyAdd metadata_key field
Invalid status transitionAttempting to change from a terminal statusCOMPLETED and CANCELLED are final states