Search by

advero / advero-php

cuongcds

Server-side PHP API client for the Advero API

Package info

github.com/cuongcds/advero-php

pkg:composer/advero/advero-php

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

0.1.0 2026-09-23 05:31 UTC

This package is auto-updated.

Last update: 2026-09-23 05:58:29 UTC


README

Server-side PHP API client for the Advero API (api-advero.domain.com). Lets a publisher/advertiser with a PHP backend call Advero directly — create/manage Campaigns, sync Wallet state, register/verify Properties, book marketplace inventory, pull reports — without going through the Advero UI.

This is distinct from sdks/advero-sdk (the browser-side JS snippet publishers embed to display ads): advero-php is a server-to-server HTTP client, has no DOM/browser code, and authenticates with an API key/secret instead of a verified property key.

Install

composer require advero/advero-php

Requires PHP >= 8.1 with the curl and json extensions (both are part of a standard PHP install).

Authentication

Every request is authenticated as Authorization: Bearer {apiKey}:{secret}, tied to your Organization.

To get an API key/secret pair:

  1. Log in to Advero and go to Organization settings > API credentials (/organization/api-credentials).
  2. Click Create API credential.
  3. Copy both the API key and API secret shown — the secret is displayed only once, right after creation, and cannot be viewed again (revoke and create a new one if you lose it).

Client never assumes a default host — baseUrl is always a required constructor argument, so you always point it explicitly at your Advero instance (e.g. https://api-advero.domain.com). Ask whoever manages your Advero deployment for the correct value if you don't already know it.

use Advero\Client;
use Advero\Exception\AdveroApiException;

$client = new Client('https://api-advero.domain.com', $apiKey, $apiSecret);

Missing baseUrl, apiKey, or apiSecret throws InvalidArgumentException immediately, before any request is made.

Usage

<?php
require __DIR__ . '/vendor/autoload.php';

use Advero\Client;
use Advero\Exception\AdveroApiException;

$client = new Client('https://api-advero.domain.com', $apiKey, $apiSecret);

try {
    // Wallet
    $wallet = $client->getWallet();
    echo $wallet['available_balance'];

    // Properties (publisher side)
    $property = $client->createProperty([
        'name' => 'My Blog',
        'domain' => 'blog.example.com',
        'verify_method' => 'html_tag', // or 'dns_txt'
    ]);
    $client->verifyProperty($property['id']);

    $placement = $client->createPlacement($property['id'], [
        'name' => 'Sidebar 300x250',
        'ad_format_id' => 1,
    ]);

    // Marketplace (advertiser side)
    $inventory = $client->getInventory(['keyword' => 'tech', 'per_page' => 20]);
    foreach ($inventory['data'] as $item) {
        // $inventory also carries $inventory['meta'] (total/page/per_page)
    }

    $quote = $client->quoteInventory($placement['id'], [
        'pricing_plan_id' => 42,
        'start_date' => '2026-10-01',
        'end_date' => '2026-10-07',
    ]);

    // Campaigns
    $campaign = $client->createCampaign([
        'name' => 'Q4 Launch',
        'start_date' => '2026-10-01',
        'end_date' => '2026-10-31',
    ]);

    $lineItem = $client->createCampaignLineItem($campaign['id'], [
        'placement_id' => $placement['id'],
        'pricing_plan_id' => 42,
        'start_date' => '2026-10-01',
        'end_date' => '2026-10-07',
        // 'max_budget' => 500000, // required only when the pricing plan is CPC
    ]);

    $client->createLineItemCreative($lineItem['id'], [
        'file_url' => 'https://cdn.example.com/creatives/banner.png',
        'width' => 300,
        'height' => 250,
        'click_url' => 'https://example.com/landing',
    ]);

    $client->startCampaign($campaign['id']);

    // Reports
    $report = $client->getCampaignReport($campaign['id'], [
        'from_date' => '2026-10-01',
        'to_date' => '2026-10-31',
    ]);
} catch (AdveroApiException $e) {
    // API responded with { "error": { "message", "code" } }
    echo $e->getMessage() . ' (' . $e->getApiCode() . ', HTTP ' . $e->getStatusCode() . ')';
} catch (\RuntimeException $e) {
    // Network error, timeout, or a non-JSON response
    echo $e->getMessage();
}

More end-to-end examples (publisher onboarding, advertiser booking flow including the CPC max_budget case, pulling reports) are in examples/. For a fuller integration — a widget-based Advero overview dashboard dropped into an existing CodeIgniter 3.1.13 project — see examples/advero-ci3/.

Response shape

Advero's api/* endpoints (see Partner_api_controller) return a consistent envelope:

  • Success: { "data": ..., "meta": {...}? }, HTTP 200.
  • Error: { "error": { "message": "...", "code": "..." } }, HTTP 4xx/5xx.

Every Client method returns the decoded data directly as an associative array (or list of arrays for a collection). If the response also has a meta block (paginated endpoints), the method instead returns ['data' => ..., 'meta' => ...] so pagination info isn't discarded — see getInventory()/getWalletTransactions() in the example above.

On a non-2xx response, Client throws Advero\Exception\AdveroApiException with getMessage()/getApiCode()/getStatusCode() populated from the error envelope, so callers never need to parse the JSON error body themselves.

Method reference

Domain Methods Endpoint(s) covered
Properties getProperties(), createProperty(), getProperty(), updateProperty(), deleteProperty(), verifyProperty(), getPropertyPlacements(), createPlacement() GET/POST api/properties, GET/PUT/DELETE api/properties/{id}, POST api/properties/{id}/verify, GET/POST api/properties/{id}/placements
Placements getPlacement(), updatePlacement(), deletePlacement() GET/PUT/DELETE api/placements/{id}
Pricing plans getPricingPlans(), createPricingPlan(), getPricingPlan(), updatePricingPlan(), deletePricingPlan() GET/POST api/pricing-plans, GET/PUT/DELETE api/pricing-plans/{id}
Marketplace getInventory(), quoteInventory() GET api/inventory, GET api/inventory/{id}/quote
Wallet getWallet(), getWalletTransactions() GET api/wallet, GET api/wallet/transactions
Campaigns getCampaigns(), createCampaign(), getCampaign(), updateCampaign(), deleteCampaign(), getCampaignLineItems(), createCampaignLineItem(), startCampaign() GET/POST api/campaigns, GET/PUT/DELETE api/campaigns/{id}, GET/POST api/campaigns/{id}/line-items, POST api/campaigns/{id}/start
Line items getLineItem(), updateLineItem(), deleteLineItem(), createLineItemCreative() GET/PUT/DELETE api/line-items/{id}, POST api/line-items/{id}/creative
Creatives getCreative(), deleteCreative() GET/DELETE api/creatives/{id}
Reports getCampaignReport(), getPublisherReport(), getAdvertiserReport() GET api/reports/campaigns/{id}, GET api/reports/publisher, GET api/reports/advertiser

Auth/Organization endpoints are intentionally not covered — they authenticate a logged-in user/session via JWT (Api_Controller), a different mechanism from the Organization API key/secret this SDK uses (Partner_api_controller), and are out of scope for a server-to-server client.

Design notes / implementation choice

  • Uses PHP's built-in curl extension rather than an HTTP client library (e.g. Guzzle) to keep the package dependency-free — only ext-curl and ext-json, both standard in any PHP 8.1 install. If your project already depends on Guzzle for other reasons, you can still use this package alongside it; Client doesn't require or conflict with any specific HTTP stack.
  • Field/query-param validation (required fields per pricing plan type, etc.) is intentionally left to the API itself — the SDK passes your $data/ $params array through as-is and surfaces any 422 VALIDATION_ERROR via AdveroApiException, so the contract stays in exactly one place (application/controllers/api/*) instead of being duplicated in the client.