Authentication & headers
Learn to authenticate Display API requests using secure credentials and headers.
Overview
All Walmart Connect Display API requests require RSA-based authentication and a defined set of request headers.
Authentication is used to:
- Verify partner identity
- Protect request integrity
- Secure advertiser data
- Enable request tracing and troubleshooting
This guide explains how authentication works, which headers are required, and how to successfully make your first API request.
How authentication works
Before making API requests, partners must:
1. Generate credentials
Create RSA keys and obtain the required API credentials.
2. Select environment
Choose Sandbox or Production.
3. Generate headers
Create authentication signatures and timestamps.
4. Send request
Include all required headers and request parameters.
5. Validate response
Confirm successful authentication and endpoint access.
Before you begin
- Valid API credentials (learn more about generating credentials)
- RSA key pair configured
- Consumer ID issued
- Auth token issued
- Key version issued
- Sandbox or Production environment selected
Required headers
Every API request must include the required authentication headers.
Headers
| Header Name | Description | Required | Values |
|---|---|---|---|
Authorization | The token will provide you the access to the API. It is same for all advertisers you access through the API. | Y | Please utilize the generated auth_token shared with you at the time of partner onboarding from the Getting Started Guide |
Content-Type | Format of the message body | Y | application/json |
WM_CONSUMER.ID | Unique ID for consumer. We will provide you the consumer ID to access the API. It is same for all advertisers you access through the API. | Y | Please use the generated ConsumerId shared with you at the time of partner onboarding. Refer to the Getting Started Guide for more information |
WM_SEC.AUTH_SIGNATURE | Auth signature as an API key. | Y | Use the signature generator code from Getting Started Guide to generate this value |
WM_SEC.KEY_VERSION | Key version. We will provide you with the KEY VERSION to access the API. It is same for all advertisers you access through the API. | Y | 1 |
WM_CONSUMER.intimestamp | Timestamp for which the auth signature is generated. Use Unix epoch format for the timestamp. | Y | Use the signature generator code from Getting Started Guide to generate this value |
All header names are case-sensitive.
Understanding the required headers
| Header | Source | Purpose |
|---|---|---|
Authorization | Walmart-issued | Authenticates the request |
WM_CONSUMER.ID | Walmart-issued | Identifies the partner |
WM_SEC.KEY_VERSION | Walmart-issued | Identifies the active RSA key version |
WM_SEC.AUTH_SIGNATURE | Partner-generated | Signs the request using the private key |
WM_CONSUMER.intimestamp | Partner-generated | Timestamp used during signature generation |
Content-Type | Partner-generated | Indicates request payload format |
Environment configuration
Sandbox and Production environments use separate credentials and endpoints.
| Environment | Base URL | Credentials |
|---|---|---|
| Sandbox | https://developer.api.us.stg.walmart.com/api-proxy/service/display/api/v1 | Sandbox RSA keys and auth token |
| Production | Provided by Partner team | Production RSA keys and auth token |
ImportantSandbox and Production credentials are not interchangeable.
Do not use Sandbox credentials against Production endpoints or Production credentials against Sandbox endpoints.
Making your first request
Use the example below to understand how required headers should be included in a Display API request.
Cookie-related authentication issueClear all cookies before making API requests.
If testing via cURL, do not use a cookie jar.
A
403response on POST or PUT requests — but not GET requests — is commonly caused by cookie-related issues.
Example request
Authenticated API request
curl -X POST \
'https://developer.api.us.stg.walmart.com/api-proxy/service/display/api/v1/api/v1/snapshot/entity' \ -H "Authorization: Bearer <auth_token>" \ -H "WM_CONSUMER.ID: <consumer_id>" \ -H "WM_SEC.KEY_VERSION: <key_version>" \ -H "WM_SEC.AUTH_SIGNATURE: $SIGNATURE" \ -H "WM_CONSUMER.INTIMESTAMP: $TIMESTAMP" \ -H "Content-Type: application/json" \ -d '{"advertiserId":123456}'Replace all placeholder values with credentials assigned to your partner account.
Generating authentication signatures
Authentication signatures are generated using:
- Your private RSA key
- Consumer ID
- Timestamp
- Key version
The resulting signature is passed through WM_SEC.AUTH_SIGNATURE and paired with WM_CONSUMER.intimestamp. Both values are required for authenticated requests.
Sample implementations
Java example
package com.walmart.wpa; import java.io.*; import java.security.KeyRep; import java.security.PrivateKey; import java.security.Signature; import java.util.*; public class SignatureGenerator { public static void main(String args[]) throws IOException { // Consumer ID provided by Walmart String consumerId = "consumerId"; String privateKeyVersion = "1"; // Location to private key file for which public key file was shared with Walmart String privateKey = readFile("./agency_private_key.pem"); long inTimestamp = System.currentTimeMillis(); Map<String, String> map = new HashMap<>(); map.put("WM_CONSUMER.ID", consumerId); map.put("WM_CONSUMER.INTIMESTAMP", Long.toString(inTimestamp)); map.put("WM_SEC.KEY_VERSION", privateKeyVersion); String[] array = canonicalize(map); String auth_signature = null; try { auth_signature = generateSignature(privateKey, array[1]); // Auth_signature and Timestamp needed to call Display API // Valid for 300 seconds System.out.println("Signature: \t" + auth_signature); System.out.println("Intimestamp: \t" + inTimestamp); } catch (Exception e) { e.printStackTrace(); } } private static String readFile(String path) throws IOException { BufferedReader br = new BufferedReader(new FileReader(path)); try { StringBuilder sb = new StringBuilder(); String line = br.readLine(); while (line != null) { if (line.contains("BEGIN")) { line = br.readLine(); continue; } if (line.contains("END")) break; sb.append(line); line = br.readLine(); } return sb.toString(); } finally { br.close(); } } public static String generateSignature(String key, String stringToSign) throws Exception { Signature signatureInstance = Signature.getInstance("SHA256WithRSA"); ServiceKeyRep keyRep = new ServiceKeyRep(KeyRep.Type.PRIVATE, "RSA", "PKCS#8", Base64.getDecoder().decod e(key)); PrivateKey resolvedPrivateKey = (PrivateKey) keyRep.readResolve(); signatureInstance.initSign(resolvedPrivateKey); byte[] bytesToSign = stringToSign.getBytes("UTF-8"); signatureInstance.update(bytesToSign); byte[] signatureBytes = signatureInstance.sign(); String signatureString = Base64.getEncoder().encodeToString(signatureBytes); return signatureString; } protected static String[] canonicalize(Map<String, String> headersToSign) { StringBuffer canonicalizedStrBuffer = new StringBuffer(); StringBuffer parameterNamesBuffer = new StringBuffer(); Set<String> keySet = headersToSign.keySet(); // Create sorted key set to enforce order on the key names SortedSet<String> sortedKeySet = new TreeSet<String>(keySet); for (String key : sortedKeySet) { Object val = headersToSign.get(key); parameterNamesBuffer.append(key.trim()).append(";"); canonicalizedStrBuffer.append(val.toString().trim()).append("\n"); } return new String[] {parameterNamesBuffer.toString(), canonicalizedStrBuffer.toString()}; } static class ServiceKeyRep extends KeyRep { private static final long serialVersionUID = -7213340660431987616L; public ServiceKeyRep(Type type, String algorithm, String format, byte[] encoded) { super(type, algorithm, format, encoded); } protected Object readResolve() throws ObjectStreamException { return super.readResolve(); } } } Python example
(Note: this example requires the pycryptodome module to be installed – pip install pycryptodome) #!/usr/bin/env python import time import pycryptodome from Crypto.PublicKey import RSA from Crypto.Signature import PKCS1_v1_5 from Crypto.Hash import SHA256 from base64 import b64encode, b64decode key = open(r"{UPDATE_THIS}/agency_private_key.pem", "r").read() rsakey = RSA.importKey(key) signer = PKCS1_v1_5.new(rsakey) digest = SHA256.new() epoch_time = int(time.time()) * 1000 consumerId = '{CONSUMERID}' keyVersion = '1' data = consumerId + '\n' + str(epoch_time) + '\n' + keyVersion + '\n' digest.update(data.encode("utf8")) sign = signer.sign(digest) final = b64encode(sign) # Auth_signature and Timestamp needed to call Display API # Valid for 300 seconds print ('Timestamp:', epoch_time) print ('Signature:' , b64encode(sign).decode())
NoteSignature generation examples are provided as reference implementations.
Partners may generate signatures using any language or framework that supports RSA SHA-256 signing.
Common authentication issues
| Issue | Potential Cause |
|---|---|
401 Unauthorized | Authentication credentials are missing or invalid, requiring the client to provide valid credentials. |
403 Forbidden | Client has valid credentials but lacks the necessary permissions to access the resource. |
| Signature validation failure | Incorrect private key or key version |
| Timestamp validation failure | Expired or improperly generated timestamp |
| Successful GET requests but failed POST/PUT requests | Cookie jar or browser cookie interference |
| Endpoint authorization errors | Access type does not support requested workflow |
Authentication best practices
Security
- Store private keys in a secure secrets management system
- Rotate RSA keys periodically
- Increment key version when rotating keys
- Never log private keys or raw signatures
Reliability
- Generate a unique correlation ID for every request
- Retry only transient errors such as 429 or 500
- Use exponential backoff when retrying
- Avoid cookie jars in automated workflows
What happens next
After authentication is working successfully:
- Validate advertiser account access
- Test endpoint permissions
- Confirm Sandbox connectivity
- Begin implementing campaign, reporting, audience, or creative workflows
Related pages
Updated about 5 hours ago
