TestingAPIs is still being built. If something breaks, email support@testingapis.com.

OAuth 1.0a

OAuth 1.0a (RFC 5849): signed requests for testing client signing code. Supports HMAC-SHA1, HMAC-SHA256, HMAC-SHA512 and PLAINTEXT signatures, two-legged (consumer-only) requests, a static access token, and the three-legged flow: request token, authorize, access token. Authorization is auto-approved as user apibee.

Your account unlocks these endpoints. Try it on each endpoint's page sends your key for you; from your own code, send a key from your API keys page in the X-TestingApis-Key header.

These endpoints need a free account. Create one or sign in to see their details and try them here.

Example request

Call a protected resource with an OAuth 1.0a signed request. Full reference and a Send button.

cURL
curl -X GET "https://api.testingapis.com/api/auth/oauth1" \
  -H 'Authorization: OAuth oauth_consumer_key="apibee-consumer-key", oauth_token="apibee-access-token", oauth_signature_method="PLAINTEXT", oauth_signature="apibee-consumer-secret%26apibee-token-secret"' \
  -H "X-TestingApis-Key: YOUR_API_KEY"
Response · 200 OK
{
  "authenticated": true,
  "scheme": "oauth1",
  "legs": "three-legged",
  "signatureMethod": "PLAINTEXT",
  "parametersIn": "Authorization header",
  "consumerKey": "apibee-consumer-key",
  "token": "apibee-access-token",
  "tokenExpiresIn": null,
  "user": {
    "username": "apibee",
    "name": "TestingAPIs Tester",
    "email": "tester@example.com"
  },
  "timestamp": null,
  "nonce": null,
  "signatureBaseString": null
}

Sign in to see the details

The parameters, request and response examples and the live Try it panel for these endpoints are for signed-in members. Accounts are free and take a few seconds to create.

Signing rules

Every signed request follows these rules: the request token and access token steps, and the protected resource. The authorize step is a browser page and is not signed.

  • Credentials. Consumer key and secret apibee-consumer-key / apibee-consumer-secret. Static access token and secret apibee-access-token / apibee-token-secret, which never expire and belong to user apibee.
  • Signature methods. HMAC-SHA1, HMAC-SHA256, HMAC-SHA512 and PLAINTEXT. RSA-SHA1 is not supported.
  • Signing key. percentEncode(consumer_secret) + "&" + percentEncode(token_secret). The token secret is empty when there is no token, so the key ends in &. With PLAINTEXT the key is the signature, encoded once more for the header: apibee-consumer-secret%26apibee-token-secret.
  • One place for the parameters. The Authorization: OAuth … header (recommended), the query string, or an application/x-www-form-urlencoded body. Sending them in two places gets 400 parameter_rejected.
  • What is signed. Query parameters and the fields of a form-encoded body are part of the signature. Other body types are not signed.
  • Timestamp and nonce. oauth_timestamp must be within 5 minutes of server time, and each oauth_nonce works once. Both may be left out for PLAINTEXT only.
  • Version. oauth_version is optional. If sent, it must be 1.0.

Errors

Errors are JSON with status, error, message and oauth_problem. 401 responses also carry details (null when there is nothing to add) and a WWW-Authenticate: OAuth realm="apibee", oauth_problem="…" header. The authorize step returns its token problems with status 400.

oauth_problemStatusMeaning
parameter_absent400A required parameter is missing, such as oauth_callback in step 1 or oauth_verifier in step 3. A request with no OAuth parameters at all gets 401.
parameter_rejected400A duplicated parameter, OAuth parameters in more than one place, a bad oauth_callback, or an oauth_token sent to the request token step. A wrong oauth_verifier in step 3 gets 401.
version_rejected400oauth_version is not 1.0.
signature_method_rejected400Not HMAC-SHA1, HMAC-SHA256, HMAC-SHA512 or PLAINTEXT. RSA-SHA1 is not supported.
consumer_key_unknown401The consumer key is not apibee-consumer-key.
token_rejected401Unknown token, or a request token sent to the protected resource before it was exchanged.
token_expired401A request token older than 10 minutes, or an access token older than 1 hour.
token_used401The request token was already exchanged for an access token.
timestamp_refused401More than 5 minutes from server time. details.oauth_acceptable_timestamps gives the accepted range.
nonce_used401The nonce was already used with this timestamp.
signature_invalid401The signature doesn't match. details.signatureBaseString is the string the server signed.
permission_unknown401The request token hasn't been authorized yet.

Debugging a signature mismatch

On signature_invalid, details.signatureBaseString holds the string the server signed. Diff it against the one your client built. The usual causes are a different URL (scheme, host or a trailing slash), a query or form parameter missing from the base string, and spaces encoded as + instead of %20.

401 Unauthorized
{
  "status": 401,
  "error": "Unauthorized",
  "message": "Signature mismatch.",
  "oauth_problem": "signature_invalid",
  "details": {
    "hint": "oauth_signature = base64(HMAC-SHA1(key: consumer_secret&token_secret, message: signature base string)). Compare your base string with the one below.",
    "signatureBaseString": "GET&https%3A%2F%2Fapi.testingapis.com%2Fapi%2Fauth%2Foauth1&oauth_consumer_key%3Dapibee-consumer-key%26oauth_nonce%3Dc50495d3b6c48421%26oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1791639304%26oauth_token%3Dapibee-access-token%26oauth_version%3D1.0"
  }
}