API Documentation

Erste Schritte

Authentication

Every endpoint except /openapi requires an authenticated WordPress user. Three methods work; each resolves to a user, and that user's capabilities decide what the request may access.

Application passwords

Built into WordPress. Create one under Users → Profile → Application Passwords, then send it with HTTP Basic auth:

curl https://example.com/wp-json/wcusage/v2/affiliates \
  -u "admin:abcd efgh ijkl mnop qrst uvwx"

An application password carries the user's full permissions, on this API and on every other WordPress endpoint. It is the quickest way to get started, and fine for a trusted server-to-server integration you control.

API keys

Plugin API keys are the better choice for anything you do not fully control, because they can be scoped, expired and revoked without touching the WordPress account. Create one under Coupon Affiliates → Admin Tools → API, or through the key management endpoints.

A key looks like wcus_9f2c1e4a… and is shown once, at creation — only a SHA-256 hash is stored. Send it as a bearer token:

curl https://example.com/wp-json/wcusage/v2/me \
  -H "Authorization: Bearer wcus_9f2c1e4a7b3d5e6f8a9b0c1d2e3f4a5b6c7d8e9f"

If your client cannot set the Authorization header (some hosts strip it), an alternative header is accepted:

X-WCUsage-API-Key: wcus_9f2c1e4a7b3d5e6f8a9b0c1d2e3f4a5b6c7d8e9f

Every key:

  • Acts as one WordPress user. A key created against an affiliate's account can only ever reach that affiliate's own data, whatever it asks for. A key against an admin account has admin access.
  • Carries scopes that restrict it further, on top of that user's capabilities.
  • Works only on this plugin's namespaceswcusage/v2 und woo-coupon-usage/v1. Presenting one to a core or WooCommerce endpoint fails with 403 wcusage_api_key_wrong_namespace. An API key is not a general-purpose WordPress credential.
  • Can have an optional expiry date, and can be revoked at any moment. Revocation takes effect on the very next request.
  • Records a last used timestamp, updated at most once every five minutes — a liveness signal, not an audit log.

Scopes

ScopeGrants
readEvery GET endpoint: affiliates, coupons, stats, referred orders, payouts, registrations, clicks, events, reports.
writeCreating and changing data: payout requests, payout status changes, registration approval and decline, and refreshing stored coupon stats.
manageManaging the API itself: creating and revoking API keys, and — on PRO — creating, editing, testing and deleting webhooks.
Warning
manage is not a peer of the other two. A key holding it can issue itself another key with any scope, and can point a webhook at a server of its choosing. Treat it as full access for the user behind the key, and give it only to integrations that genuinely administer the API.

Scopes apply nur to API keys. With an application password or a logged-in cookie, auth.scopes ist null and access is governed purely by capabilities. A key missing a required scope receives 403 with the code wcusage_api_insufficient_scope.

On the legacy woo-coupon-usage/v1 namespace, which predates scopes, keys are held to a fail-closed default: GET, HEAD und OPTIONS need read, anything else needs write.

Tip
When connecting an AI agent or a third-party SaaS, create a dedicated read-only key on a dedicated account. It cannot change anything on your site whatever the client does, and you can revoke it without disturbing anything else.

Same-site JavaScript can use the logged-in cookie with a REST nonce, exactly as with any WordPress REST endpoint:

fetch( '/wp-json/wcusage/v2/me', {
  headers: { 'X-WP-Nonce': wpApiSettings.nonce },
  credentials: 'same-origin'
} ).then( r => r.json() );

HTTPS

Bearer tokens are credentials, so they are refused over plain HTTP unless wp_get_environment_type() Berichte local oder development. Such a request fails with 401 wcusage_api_https_required. Die wcusage_api_require_https filter can override it — do that only if you know exactly why.

Failed-attempt lockout

An address that presents 20 invalid keys within 15 minutes is refused further attempts with 429 wcusage_api_too_many_auth_failures until the window rolls over. Counts are kept per IP address, so one client cannot lock out another. Adjust with the wcusage_api_max_auth_failures filter.

Who am I?

Whatever method you use, GET /me reports exactly what the request is authenticated as, what access level it has, and which scopes are in force. Call it first when setting up any integration.