Hello!
I'm using this article to receive the token to get access to the API.
I created new Apple ID, set up Search Ads, and invite this new user from my main account (with access to ads/campaigns) with shared access to data through API.
In parallel I generated two keys (private and public) and uploaded public key.
So, I got clientId, teamId and keyId. Don't know why, but clientId and teamId in my case are the same. Then I used Python example from docs to create JWT token (or client_secret).
I got client_secret and then tried to send POST request to get access_token.
I used CURL from example (with my data):
curl -X POST
-H 'Host: appleid.apple.com'
-H 'Content-Type: application/x-www-form-urlencoded'
https://appleid.apple.com/auth/oauth2/token?grant_type=client_credentials&
client_id=id_here&client_secret=jwt_here&scope=searchadsorg
But I always receives 400 error:
{
"error": "invalid_client"
}
How to fix it? Did I miss something?
Fixed it. Generated client_secret was invalid (but API returns invalid_client). If someone will need it, i share here working Java example to get JWT token:
import io.jsonwebtoken.JwsHeader;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
import java.io.Reader;
import java.io.StringReader;
import java.security.Key;
import java.security.KeyPair;
import java.security.Security;
import java.util.Date;
public class AsaToken {
public static void main(String[] args) throws Exception {
Key key = getKey();
String clientId = "SEARCHADS...";
String teamId = "SEARCHADS...";
String keyId = "your_key;
String audience = "https://appleid.apple.com";
String alg = "ES256";
final int expiration = 1000 * 60 * 5;
JwtBuilder token = Jwts.builder()
.setHeaderParam(JwsHeader.KEY_ID, keyId)
.setHeaderParam(JwsHeader.ALGORITHM,alg)
.setIssuer(teamId)
.setAudience(audience)
.setSubject(clientId) // app id com.app.id
.setExpiration(new Date(System.currentTimeMillis() + expiration))
.setIssuedAt(new Date(System.currentTimeMillis()))
.signWith(key, SignatureAlgorithm.ES256);// ECDSA using P-256 and SHA-256
System.out.println(token.compact());
}
static Key getKey () throws Exception {
Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
Reader rdr = new StringReader("-----BEGIN EC PRIVATE KEY-----\n" +
"MHcCAQEEIGW/yC+S0umaZQ7NC+/YR6KYsMEBNZK6/dLeIfbeS0QRoAoGCCqGSM49\n" +
"AwEHoUQDQgAEh5AFB3WTDy9Zvo2PbgwNnCP39+PezA7AG/qT09cBLIBIBa0kKbEB\n" +
"fcJ910wkr9Ah+NrtUgCeQOE8vx8ObmjMeg==\n" +
"-----END EC PRIVATE KEY-----");
Object parsed = new org.bouncycastle.openssl.PEMParser(rdr).readObject();
KeyPair pair = new JcaPEMKeyConverter().getKeyPair((org.bouncycastle.openssl.PEMKeyPair)parsed);
return pair.getPrivate();
}
}