Share via

rest API showing error

confidanto 0 Reputation points
2025-10-30T05:29:39.75+00:00

Submit: 400 {"OperationErrors":[{"Code":100,"ErrorCode":"NullRequest","Details":null,"Message":"The request message is null."}],"BatchErrors":[],"TrackingId":"65602e3d-f6ff-4968-920c-e420989c9e31","Type":"ApiFaultDetail"}

Traceback (most recent call last):

File "C:\yourpath\Sonu\Desktop\microsoft-ads-api\test.py", line 173, in <module>

raise Exception("Submit failed")

Exception: Submit failed

# import requests
# import time
# from flask import Blueprint, request, jsonify

# microsoft_ads_metrics = Blueprint('microsoft_ads_metrics', __name__)


# @microsoft_ads_metrics.route("/api/microsoft/campaigns-with-metrics", methods=["POST"])
# def get_campaigns_with_metrics():
#     """
#     Input (REST version):
#     {
#         "access_token": "your_access_token",
#         "customer_id": "your_customer_id",
#         "account_id": "your_account_id"
#     }
#     """
#     try:
#         data = request.json
#         access_token = data.get("access_token")
#         customer_id = data.get("customer_id")
#         account_id = data.get("account_id")

#         if not all([access_token, customer_id, account_id]):
#             return jsonify({"error": "Missing required parameters: access_token, customer_id, account_id"}), 400

#         headers = {
#             "Authorization": f"Bearer {access_token}",
#             "Content-Type": "application/json",
#             "DeveloperToken": DEVELOPER_TOKEN,
#             "CustomerId": str(customer_id),
#             "AccountId": str(account_id)
#         }

#         # Step 1️⃣: Submit Report Request (REST endpoint)
#         submit_url = "https://reporting.api.bingads.microsoft.com/Reporting/v13/Reports/SubmitGenerateReport"

#         body = {
#             "ReportRequest": {
#                 "ReportName": "Campaign Performance Report",
#                 "Aggregation": "Daily",
#                 "Columns": [
#                     "TimePeriod",
#                     "AccountName",
#                     "CampaignName",
#                     "CampaignId",
#                     "Clicks",
#                     "Impressions",
#                     "Ctr",
#                     "AverageCpc",
#                     "Spend",
#                     "Conversions"
#                 ],
#                 "Format": "Csv",
#                 "ReportType": "CampaignPerformanceReport",
#                 "Scope": {
#                     "AccountIds": [int(account_id)]
#                 },
#                 "Time": {
#                     "PredefinedTime": "Last30Days"
#                 }
#             }
#         }

#         print("🟢 Submitting report request...")
#         submit_response = requests.post(submit_url, headers=headers, json=body)

#         if submit_response.status_code != 200:
#             return jsonify({
#                 "error": f"Submit failed ({submit_response.status_code})",
#                 "details": submit_response.text
#             }), submit_response.status_code

#         submit_json = submit_response.json()
#         print("Submit response:", submit_json)

#         # Extract ReportRequestId
#         report_request_id = submit_json.get("ReportRequestId")
#         if not report_request_id:
#             return jsonify({
#                 "error": "Missing ReportRequestId in response",
#                 "details": submit_json
#             }), 400

#         # Step 2️⃣: Poll until report is ready
#         poll_url = "https://reporting.api.bingads.microsoft.com/Reporting/v13/Reports/PollGenerateReport"
#         max_attempts = 12  # up to ~60 seconds
#         for attempt in range(max_attempts):
#             print(f"⏳ Poll attempt {attempt + 1}/{max_attempts}")
#             poll_response = requests.post(poll_url, headers=headers, json={"ReportRequestId": report_request_id})
            
#             if poll_response.status_code != 200:
#                 time.sleep(5)
#                 continue

#             poll_json = poll_response.json()
#             print("Poll response:", poll_json)

#             status = poll_json.get("ReportRequestStatus", {}).get("Status")
#             if status == "Success":
#                 download_url = poll_json["ReportRequestStatus"].get("ReportDownloadUrl")
#                 if not download_url:
#                     return jsonify({"error": "No ReportDownloadUrl found"}), 400
                
#                 print("✅ Report ready, downloading CSV...")
#                 csv_response = requests.get(download_url)
#                 if csv_response.status_code == 200:
#                     return jsonify({
#                         "success": True,
#                         "report_request_id": report_request_id,
#                         "csv_data": csv_response.text
#                     })
#                 else:
#                     return jsonify({
#                         "error": f"Download failed ({csv_response.status_code})"
#                     }), csv_response.status_code

#             elif status in ["Pending", "InProgress"]:
#                 time.sleep(5)
#                 continue
#             else:
#                 return jsonify({
#                     "error": f"Report generation failed (status: {status})"
#                 }), 400

#         return jsonify({"error": "Report generation timeout"}), 408

#     except Exception as e:
#         print("❌ Unexpected error:", e)
#         return jsonify({"error": str(e)}), 500
import requests, time

ACCESS_TOKEN = "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwia2lkIjoiZ0lpZlY5OHcwRjZkQW8ydTFXa05oZzBZYWRFMkg4a0dVb1BHcUVnazJ3dyIsInppcCI6IkRFRiJ9..WBaWKsMxkuInnjK5HC5uNA.9cBWynADp_D46C3R9P65IiPjl2ZjlN8cl1S5H-cms3bUs72IINdem2w_ZpSozWYUIYZewi8kYbhPcIjE-7R5ClWGUSXx7uWNdb_ptStwxL2FgZNm-ocgJKPAqSkd8s4HBOewBL1lqzyqaSQ7lHZdweNAzEhLq_yGqiGeQJfEszDyjQHPlG3NOVg4vtQd4C4fJsML74RQnJLZTjeflIfmj7mBetU6toqlmzyqmNFcLfRL4ox2RgoW2_KRki25FFGH4aIe8Cnh38Nn-zhGcW8FfMsysgNLSzfCwpzyuCKY7qJTokfno4cq1-OnGbU79Pt6XGYuoYei4LtZ1hWRYfYPgXzMPg-yRh1R0g0r2ACl4RM1s-4e0IBkc9bioCAt2ckKXH_RfPdWn65Yd7VfbBYGTUVOolkfeQpUaHa34EY2JpZRVFVwEgpLrsBFme8-13Y-CjU52YB4G8-QGix66kQ-TBS55FjXmyYXWW8yF8_rSy9_ri76X41-J_wFPdPYKOZrooPMXRHLkB2WHbeY9gy8NYHHqh_1MwzPNFh9Qk2W6-AMUszc92TWoNqPu28Vc6tR0AvLBMRh78Zs8XrkTzkzjSI8bRPkYqRXucl0pwe4TnVBQlVjeMP_kX6MKILf0lUO2E4z73JqB7uYS9AannTJaWDJp-lB_pWLMkB39lgdq-UOr2rg5Ow_CPFwwhpr0Vw86LYlaj0NOMbeopm6pxsffWF_zgBXPKmFVv1fiBwgSv-mc_n6_E28QMbNaKzCqlITUiaSl_Vl-SsRM64SCpKuLLIeqXWUnWklw6rilFUohGLy349BQRQnHGVeZWHdVYHVSluSNYQpu7j5yYrhqeNo3DlnK_AO8Pni2BQvtKP588GKS6q00kILho9r2iwna6XDI6A4nPObryGaYxKviSp6TlBAtvyYMwkqYf5No7a3mzQr4TAam47r9_4BYqMdvbCHWYGtgq9_E3n1vwdS8Uj4kJCm7xXXJTX1uxDQMhSz3S9pQwgtoNZyWCUD1Ym8BjTOOd4l45VIaOc5W5qEQoJboMthBaXlH2E5zlAvQCTfnqSLv0o3fdUNgiPeRp6FNRcLAE5rQO0Ho5yrQdfsqO8WMc-WI05PoHKiHpzafORIBtXLCGdbxG0RLHjb9Nf_TUok9Olj_KWcWzvwX1XkzvMTIyq4aXMm42RE4RzmODISNIwQ2V26KTaVjEKClu0qTaAGa3-aTq99vVABLfKWogEglEVm8dZg6-MwwGOApaQrEV5nFLcPu8b0jg2ntPXs6wrbf1nllR40ShTmTsxVPMRNxNGHdJvry21G0aLe1EaAA8eTtajMkQCb2h_D4Rtqagjk_5Vc-f-Vj8qYCExbe_LH_SqOk0lMd2Kt5CUyUOquDslpenSMNlZ0kzyZ2arkc3mvQK8vVQY35ESW8xmCwk19iYk02OFE2Nly7jJE2yZu7qQfTZeupiKI_Rl1YujiyCp5.TnwN2d1pB1BN__0a38d-UWrS3tCA6rm40gqoYyK_2QU"
DEVELOPER_TOKEN = "10712KL49V334137"
CUSTOMER_ID = "253889040"
ACCOUNT_ID  = 138763727

headers = {
    "Authorization": f"Bearer {ACCESS_TOKEN}",
    "DeveloperToken": DEVELOPER_TOKEN,
    "CustomerId": str(CUSTOMER_ID),
    "CustomerAccountId": str(ACCOUNT_ID),
    "Content-Type": "application/json"
}


# Step 1: Submit
submit_url = "https://reporting.api.bingads.microsoft.com/Reporting/v13/GenerateReport/Submit"

body = {
    "Type": "CampaignPerformanceReportRequest",
    "ReportType": "CampaignPerformanceReport",
    "Format": "Csv",
    "ReportName": "Campaign Performance Report",
    "ReturnOnlyCompleteData": False,
    "Aggregation": "Daily",
    "Scope": {
        "AccountIds": [ACCOUNT_ID]
    },
    "Time": {
        "PredefinedTime": "Last30Days"
    },
    "Columns": [
        "TimePeriod", "AccountName", "CampaignName", "CampaignId",
        "Clicks", "Impressions", "Ctr", "AverageCpc", "Spend", "Conversions"
    ]
}

r = requests.post(submit_url, headers=headers, json=body)
print("Submit:", r.status_code, r.text)

if r.status_code != 200:
    raise Exception("Submit failed")

report_request_id = r.json().get("reportRequestId")
if not report_request_id:
    raise Exception("No reportRequestId returned")

# Step 2: Poll
poll_url = "https://reporting.api.bingads.microsoft.com/Reporting/v13/GenerateReport/Poll"
download_url = None

for i in range(12):
    poll_body = {"reportRequestId": report_request_id}
    poll_resp = requests.post(poll_url, headers=headers, json=poll_body)
    print("Poll:", poll_resp.status_code, poll_resp.text)
    data = poll_resp.json()
    status = data.get("reportRequestStatus", {}).get("status")
    if status == "Success":
        download_url = data["reportRequestStatus"].get("reportDownloadUrl")
        break
    elif status == "Error":
        raise Exception("Report generation failed")
    time.sleep(5)

if not download_url:
    raise Exception("Report not ready after polling")

# Step 3: Download CSV
csv_resp = requests.get(download_url)
print("CSV sample:\n", csv_resp.text[:500])
Bing | Other
Bing | Other

Miscellaneous topics that do not fit into specific categories.

0 comments No comments

1 answer

Sort by: Most helpful
  1. Anonymous
    2025-10-30T17:42:21.15+00:00

    Dear confidanto,

    Thank you for reaching out to the Microsoft Q&A Forum.

    The error "The request message is null" indicates that the Bing Ads API is not receiving your request body properly.

    There are some issues with your code:

    • Wrong endpoint URL - You're using /GenerateReport/Submit instead of /Reports/SubmitGenerateReport
    • Incorrect header format - Missing required headers
    • Wrong body structure - Using SOAP-style structure instead of REST

    Here is the fixed code:

    import requests
    import time
    
    ACCESS_TOKEN = "eyJhbGciOiJkaXIiLCJlbmMiOiJBMjU2Q0JDLUhTNTEyIiwia2lkIjoiZ0lpZlY5OHcwRjZkQW8ydTFXa05oZzBZYWRFMkg4a0dVb1BHcUVnazJ3dyIsInppcCI6IkRFRiJ9..WBaWKsMxkuInnjK5HC5uNA.9cBWynADp_D46C3R9P65IiPjl2ZjlN8cl1S5H-cms3bUs72IINdem2w_ZpSozWYUIYZewi8kYbhPcIjE-7R5ClWGUSXx7uWNdb_ptStwxL2FgZNm-ocgJKPAqSkd8s4HBOewBL1lqzyqaSQ7lHZdweNAzEhLq_yGqiGeQJfEszDyjQHPlG3NOVg4vtQd4C4fJsML74RQnJLZTjeflIfmj7mBetU6toqlmzyqmNFcLfRL4ox2RgoW2_KRki25FFGH4aIe8Cnh38Nn-zhGcW8FfMsysgNLSzfCwpzyuCKY7qJTokfno4cq1-OnGbU79Pt6XGYuoYei4LtZ1hWRYfYPgXzMPg-yRh1R0g0r2ACl4RM1s-4e0IBkc9bioCAt2ckKXH_RfPdWn65Yd7VfbBYGTUVOolkfeQpUaHa34EY2JpZRVFVwEgpLrsBFme8-13Y-CjU52YB4G8-QGix66kQ-TBS55FjXmyYXWW8yF8_rSy9_ri76X41-J_wFPdPYKOZrooPMXRHLkB2WHbeY9gy8NYHHqh_1MwzPNFh9Qk2W6-AMUszc92TWoNqPu28Vc6tR0AvLBMRh78Zs8XrkTzkzjSI8bRPkYqRXucl0pwe4TnVBQlVjeMP_kX6MKILf0lUO2E4z73JqB7uYS9AannTJaWDJp-lB_pWLMkB39lgdq-UOr2rg5Ow_CPFwwhpr0Vw86LYlaj0NOMbeopm6pxsffWF_zgBXPKmFVv1fiBwgSv-mc_n6_E28QMbNaKzCqlITUiaSl_Vl-SsRM64SCpKuLLIeqXWUnWklw6rilFUohGLy349BQRQnHGVeZWHdVYHVSluSNYQpu7j5yYrhqeNo3DlnK_AO8Pni2BQvtKP588GKS6q00kILho9r2iwna6XDI6A4nPObryGaYxKviSp6TlBAtvyYMwkqYf5No7a3mzQr4TAam47r9_4BYqMdvbCHWYGtgq9_E3n1vwdS8Uj4kJCm7xXXJTX1uxDQMhSz3S9pQwgtoNZyWCUD1Ym8BjTOOd4l45VIaOc5W5qEQoJboMthBaXlH2E5zlAvQCTfnqSLv0o3fdUNgiPeRp6FNRcLAE5rQO0Ho5yrQdfsqO8WMc-WI05PoHKiHpzafORIBtXLCGdbxG0RLHjb9Nf_TUok9Olj_KWcWzvwX1XkzvMTIyq4aXMm42RE4RzmODISNIwQ2V26KTaVjEKClu0qTaAGa3-aTq99vVABLfKWogEglEVm8dZg6-MwwGOApaQrEV5nFLcPu8b0jg2ntPXs6wrbf1nllR40ShTmTsxVPMRNxNGHdJvry21G0aLe1EaAA8eTtajMkQCb2h_D4Rtqagjk_5Vc-f-Vj8qYCExbe_LH_SqOk0lMd2Kt5CUyUOquDslpenSMNlZ0kzyZ2arkc3mvQK8vVQY35ESW8xmCwk19iYk02OFE2Nly7jJE2yZu7qQfTZeupiKI_Rl1YujiyCp5.TnwN2d1pB1BN__0a38d-UWrS3tCA6rm40gqoYyK_2QU"
    DEVELOPER_TOKEN = "10712KL49V334137"
    CUSTOMER_ID = "253889040"
    ACCOUNT_ID = 138763727
    
    # Correct headers format
    headers = {
        "Authorization": f"Bearer {ACCESS_TOKEN}",
        "DeveloperToken": DEVELOPER_TOKEN,
        "CustomerId": CUSTOMER_ID,
        "AccountId": str(ACCOUNT_ID),
        "Content-Type": "application/json"
    }
    
    # Step 1: Submit Report - CORRECT ENDPOINT
    submit_url = "https://reporting.api.bingads.microsoft.com/Reporting/v13/Reports/SubmitGenerateReport"
    
    # Correct body structure for REST API
    body = {
        "ReportRequest": {
            "Format": "Csv",
            "Language": "English",
            "ReportName": "Campaign Performance Report",
            "ReturnOnlyCompleteData": False,
            "Aggregation": "Daily",
            "Columns": [
                "TimePeriod",
                "AccountName", 
                "CampaignName",
                "CampaignId",
                "Clicks",
                "Impressions", 
                "Ctr",
                "AverageCpc",
                "Spend",
                "Conversions"
            ],
            "Scope": {
                "AccountIds": [ACCOUNT_ID]
            },
            "Time": {
                "PredefinedTime": "Last30Days"
            }
        }
    }
    
    print("🟢 Submitting report request...")
    print(f"Headers: {headers}")
    print(f"Body: {body}")
    
    try:
        submit_response = requests.post(submit_url, headers=headers, json=body, timeout=30)
        print(f"Submit Status: {submit_response.status_code}")
        print(f"Submit Response: {submit_response.text}")
    
        if submit_response.status_code != 200:
            raise Exception(f"Submit failed with status {submit_response.status_code}")
    
        submit_json = submit_response.json()
        print(f"Submit JSON: {submit_json}")
    
        # Extract report request ID from correct path
        report_request_id = submit_json.get("ReportRequestId")
        if not report_request_id:
            raise Exception("No ReportRequestId found in response")
    
        print(f"✅ Report Request ID: {report_request_id}")
    
        # Step 2: Poll for report
        poll_url = "https://reporting.api.bingads.microsoft.com/Reporting/v13/Reports/PollGenerateReport"
    
        for attempt in range(12):
            print(f"⏳ Polling attempt {attempt + 1}/12...")
    
            poll_response = requests.post(
                poll_url, 
                headers=headers, 
                json={"ReportRequestId": report_request_id},
                timeout=30
            )
    
            print(f"Poll Status: {poll_response.status_code}")
    
            if poll_response.status_code == 200:
                poll_json = poll_response.json()
                print(f"Poll JSON: {poll_json}")
    
                status = poll_json.get("ReportRequestStatus", {}).get("Status")
    
                if status == "Success":
                    download_url = poll_json["ReportRequestStatus"].get("ReportDownloadUrl")
                    if download_url:
                        print("✅ Report ready! Downloading...")
    
                        # Step 3: Download CSV
                        csv_response = requests.get(download_url, timeout=30)
                        if csv_response.status_code == 200:
                            print("📊 CSV Data:")
                            print(csv_response.text)
                            break
                        else:
                            raise Exception(f"Download failed: {csv_response.status_code}")
                    else:
                        raise Exception("No download URL found")
                elif status in ["Pending", "InProgress"]:
                    time.sleep(5)
                    continue
                else:
                    raise Exception(f"Report generation failed with status: {status}")
            else:
                print(f"Poll failed: {poll_response.text}")
                time.sleep(5)
    
        else:
            raise Exception("Report generation timeout")
    
    except requests.exceptions.RequestException as e:
        print(f"❌ Request error: {e}")
    except Exception as e:
        print(f"❌ Error: {e}")
    
    

    I hope this could help. If you have any further issues, I'm very happy to assist.


    If the answer is helpful, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".  

    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    Was this answer helpful?

    0 comments No comments

Your answer

Answers can be marked as 'Accepted' by the question author and 'Recommended' by moderators, which helps users know the answer solved the author's problem.