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


Required headers

Every API request must include the required authentication headers.

Headers

Header NameDescriptionRequiredValues
AuthorizationThe token will provide you the access to the API. It is same for all advertisers you access through the API.YPlease utilize the generated auth_token shared with you at the time of partner onboarding from the Getting Started Guide
Content-TypeFormat of the message bodyYapplication/json
WM_CONSUMER.IDUnique 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.   YPlease 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_SIGNATUREAuth signature as an API key.YUse the signature generator code from Getting Started Guide to generate this value
WM_SEC.KEY_VERSIONKey version. We will provide you with the KEY VERSION to access the API. It is same for all advertisers you access through the API.Y1
WM_CONSUMER.intimestampTimestamp for which the auth signature is generated. Use Unix epoch format for the timestamp.YUse the signature generator code from Getting Started Guide to generate this value

All header names are case-sensitive.

Understanding the required headers

HeaderSourcePurpose
AuthorizationWalmart-issuedAuthenticates the request
WM_CONSUMER.IDWalmart-issuedIdentifies the partner
WM_SEC.KEY_VERSIONWalmart-issuedIdentifies the active RSA key version
WM_SEC.AUTH_SIGNATUREPartner-generatedSigns the request using the private key
WM_CONSUMER.intimestampPartner-generatedTimestamp used during signature generation
Content-TypePartner-generatedIndicates request payload format

Environment configuration

Sandbox and Production environments use separate credentials and endpoints.

EnvironmentBase URLCredentials
Sandboxhttps://developer.api.us.stg.walmart.com/api-proxy/service/display/api/v1Sandbox RSA keys and auth token
ProductionProvided by Partner teamProduction RSA keys and auth token
📌

Important

Sandbox 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 issue

Clear all cookies before making API requests.

If testing via cURL, do not use a cookie jar.

A 403 response 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()) 

Note

Signature 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

IssuePotential Cause
401 UnauthorizedAuthentication credentials are missing or invalid, requiring the client to provide valid credentials.
403 ForbiddenClient has valid credentials but lacks the necessary permissions to access the resource.
Signature validation failureIncorrect private key or key version
Timestamp validation failureExpired or improperly generated timestamp
Successful GET requests but failed POST/PUT requestsCookie jar or browser cookie interference
Endpoint authorization errorsAccess 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:

  1. Validate advertiser account access
  2. Test endpoint permissions
  3. Confirm Sandbox connectivity
  4. Begin implementing campaign, reporting, audience, or creative workflows

Related pages


Did this page help you?