REST API Authentication & Rate Limiting #
How the API validates requests and prevents abuse.
Authentication Method #
The Update Server API does not use WordPress authentication (nonces, cookies, or application passwords). Instead, each endpoint validates the customer's license key as part of the request processing.
Authentication flow:
- Client sends license key in POST body
- API looks up license in DDLS database (ORM first, direct SQL fallback)
- Checks: key exists, status is active, product matches
- If any check fails: returns HTTP 400 with
invalid_licenseerror code - If all checks pass: proceeds with the request
This design means the API works without any WordPress session, from any server or application.
Why License Key Authentication? #
The license key is the natural authentication credential for your customers' software. They already have it from their purchase. Using it for update checks avoids requiring a separate API key or user account for each customer installation.
Rate Limiting #
Rate limiting is per-license. The limit is configured in settings (default: 100 requests/hour).
The limit is enforced via a WP transient counter keyed on the license ID. The transient expires after 1 hour, resetting the counter.
If rate-limited: The API returns HTTP 429. The client should back off and retry after 1 hour.
Well-behaved clients should:
- Cache the update check result for 6-24 hours locally
- Only check on session startup, not on every feature use
- Not poll the API at intervals shorter than 15-60 minutes
Download Rate Limiting #
Download requests (the /dmsilm-download/ endpoint) are rate-limited per token:
- Default: 10 downloads per hour per token
- Enforced via WP transient keyed on a hash of the token
- Provides protection against a leaked token URL being used to mass-download files
ORM Fallback #
The API first tries to use the DDLS Core ORM class (DMSILM\Models\DMSILM_License) for license lookup. If the ORM class is not available (e.g., a version mismatch), it falls back to a direct SQL query. Both paths are equivalent in behavior but the ORM path is preferred for correctness.
