advero / advero-php
Server-side PHP API client for the Advero API
Requires
- php: >=8.1
- ext-curl: *
- ext-json: *
Requires (Dev)
None
Suggests
None
Provides
None
Conflicts
None
Replaces
None
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:
- Log in to Advero and go to Organization settings > API credentials
(
/organization/api-credentials). - Click Create API credential.
- 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
curlextension rather than an HTTP client library (e.g. Guzzle) to keep the package dependency-free — onlyext-curlandext-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;Clientdoesn'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/$paramsarray through as-is and surfaces any422 VALIDATION_ERRORviaAdveroApiException, so the contract stays in exactly one place (application/controllers/api/*) instead of being duplicated in the client.