WaterlyWaterlyConnect Developer Hub
Core conceptHTTP DigestSHA-256

Authenticate without sending your secret in the request.

Every Data Retrieval API request uses HTTP Digest authentication. Your client answers a short-lived server challenge with a request-specific digest calculated from your username, secret, HTTP method, and request URI.

The challenge-response exchange

Digest authentication normally takes two HTTP exchanges. This is expected behavior, not a failed login.

  1. 1Your client requests a protected route without an Authorization header.
  2. 2Waterly returns 401 Unauthorized and a WWW-Authenticate challenge containing the realm, SHA-256 algorithm, quality-of-protection value, and a short-lived nonce.
  3. 3Your client combines the challenge with the username, secret, HTTP method, and exact request URI to calculate a digest.
  4. 4The client repeats the request with a Digest Authorization header. Waterly validates the digest, token status, organization, and required scopes.
Use an HTTP Digest client. Do not build the header yourself unless your runtime has no maintained Digest implementation. Challenge values expire, and the digest must match the exact method and URI.

Keep both credential values

An authorized Waterly administrator creates an API token for one organization. The username and plaintext secret are shown together only when the token is created. The secret cannot be recovered later; create a replacement token if it is lost.

username
Required
Stable identifier for the API token. It is safe to use as an account name but should still be kept with the integration configuration.
secret
Sensitive
One-time visible credential used to calculate request digests. Store it in a secret manager or protected environment variable.
realm
server supplied
The Waterly challenge supplies Waterly Connect API. Digest clients read this value automatically.

Use curl for a first request

--digest tells curl to perform the challenge-response exchange. The first internal 401 is handled automatically, so the command prints the authenticated response.

export WATERLY_API_USERNAME="your-api-username"
export WATERLY_API_SECRET="your-api-secret"

curl --fail-with-body --silent --show-error \
  --digest \
  --user "$WATERLY_API_USERNAME:$WATERLY_API_SECRET" \
  "https://connect.waterly.com/api/organizations/v1/current"
!

Avoid command history leaks. Keep the secret in a protected environment variable or secret file. Do not paste it directly after --user in shared terminals, scripts, logs, or screenshots.

Configure application clients

Choose a maintained library that explicitly supports HTTP Digest with SHA-256 and qop=auth. Allow the library to retry after a challenge and after a stale-nonce response. Always send requests over HTTPS.

  • Use the exact request URL when the client calculates the digest, including the path and query string.
  • Re-authenticate every request, including absolute links.next and links.prev pagination URLs.
  • Set a timeout and retry only idempotent reads after network failures.
  • Never log the secret or a complete Authorization header.

Tell authentication and authorization apart

401Authentication required. Credentials are missing or invalid, the token is inactive, or the nonce is stale. A Digest client should answer the new WWW-Authenticate challenge.
403Access denied. Authentication succeeded, but the token lacks the endpoint's scope or cannot access the requested organization.
404Resource not found. Some resource lookups intentionally return the same result for a missing resource and a resource outside the token's organization.

Credential security checklist

  • Create a separate token for each integration so it can be revoked independently.
  • Grant only the scopes the integration needs: organization:read, data-model:read, and/or data-points:read.
  • Store the secret in a secret manager; do not commit it to source control or configuration templates.
  • Revoke and replace a token immediately if its secret may have been exposed.
  • Use HTTPS and validate Waterly's TLS certificate on every request.