{"id":8301,"library":"marketorestpython","title":"Marketo REST Python Client","description":"MarketoRestPython is a Python client library that wraps the Marketo REST API, providing a convenient interface for interacting with Marketo's marketing automation platform. It handles common concerns such as authentication, error handling, and API rate limiting. The library is actively maintained, with version 0.5.25 being the latest, and receives frequent updates to support new Marketo API features and address bug fixes.","status":"active","version":"0.5.25","language":"en","source_language":"en","source_url":"https://github.com/jepcastelein/marketo-rest-python","tags":["marketing","api","marketo","crm"],"install":[{"cmd":"pip install marketorestpython","lang":"bash","label":"Install latest version"}],"dependencies":[{"reason":"Used for making HTTP requests to the Marketo REST API.","package":"requests","optional":false}],"imports":[{"note":"The original, unmaintained library used 'pythonmarketo'. The actively maintained fork uses 'marketorestpython'.","wrong":"from pythonmarketo.client import MarketoClient","symbol":"MarketoClient","correct":"from marketorestpython.client import MarketoClient"}],"quickstart":{"code":"import os\nfrom marketorestpython.client import MarketoClient\n\nmunchkin_id = os.environ.get('MARKETO_MUNCHKIN_ID', 'YOUR_MUNCHKIN_ID')\nclient_id = os.environ.get('MARKETO_CLIENT_ID', 'YOUR_CLIENT_ID')\nclient_secret = os.environ.get('MARKETO_CLIENT_SECRET', 'YOUR_CLIENT_SECRET')\n\nif not all([munchkin_id, client_id, client_secret]):\n    raise ValueError(\"Marketo credentials (MUNCHKIN_ID, CLIENT_ID, CLIENT_SECRET) must be set as environment variables or provided directly.\")\n\ntry:\n    # Initialize the Marketo client\n    # api_limit and max_retry_time are optional parameters for fine-tuning\n    mc = MarketoClient(munchkin_id, client_id, client_secret, api_limit=None, max_retry_time=300)\n\n    # Example: Get activity types\n    print(\"Fetching Marketo Activity Types...\")\n    activity_types = mc.execute(method='get_activity_types')\n\n    if activity_types and activity_types.get('success'):\n        print(f\"Successfully retrieved {len(activity_types['result'])} activity types.\")\n        for activity_type in activity_types['result'][:5]: # Print first 5 for brevity\n            print(f\"  ID: {activity_type['id']}, Name: {activity_type['name']}\")\n    elif activity_types and 'errors' in activity_types:\n        print(f\"Error fetching activity types: {activity_types['errors']}\")\n    else:\n        print(\"Failed to retrieve activity types with an unknown error.\")\n\nexcept Exception as e:\n    print(f\"An error occurred: {e}\")\n","lang":"python","description":"Initializes the MarketoClient using credentials obtained from environment variables and then fetches the available Marketo activity types. This demonstrates basic client setup and an initial API call, including checking the 'success' field in the response."},"warnings":[{"fix":"Ensure all Marketo REST API calls, whether direct or via other wrappers, pass the access token in the `Authorization: Bearer <token>` header. The `marketorestpython` library itself uses this method, so updating the library should mitigate issues if you rely solely on its client.","message":"The underlying Marketo REST API will remove support for passing `access_token` as a query parameter on July 31, 2026. All API calls must use the `Authorization` HTTP header. While `marketorestpython` handles this correctly by default (passing tokens in headers), custom code or older versions bypassing the client's internal handling will break.","severity":"breaking","affected_versions":"<=0.5.25 (specifically, custom integrations not using library's default auth)"},{"fix":"Monitor your Marketo API usage against your instance's daily quota. Implement robust retry logic with exponential backoff for transient errors, but recognize that exceeding the daily quota or certain concurrent limits requires pausing or scaling your operations rather than just retrying.","message":"Marketo API requests have strict daily quotas (e.g., 50,000 calls/day) and rate limits (e.g., 100 calls/20 seconds). Exceeding the daily quota will result in a fatal error (code `1029` for 'Too many jobs in queue' or 'Export daily quota') and will stop further processing, rather than retrying indefinitely.","severity":"gotcha","affected_versions":"All versions (v0.5.15+ handles daily quota as fatal)"},{"fix":"Always check the `['success']` key in the dictionary returned by `mc.execute()` to determine if the operation was truly successful. If `False`, inspect the `['errors']` key for details on the failure, rather than relying solely on HTTP status codes.","message":"Marketo API often returns an HTTP 200 OK status even if an operation fails at the Marketo level. Success is indicated by a `success: true` field within the JSON response body. The response may contain an `errors` array with specific error codes and messages if `success` is `false`.","severity":"gotcha","affected_versions":"All versions"}],"env_vars":null,"last_verified":"2026-04-16T00:00:00.000Z","next_check":"2026-07-15T00:00:00.000Z","problems":[{"fix":"Verify that your `client_id` and `client_secret` are correct and have not expired. These can be found in Marketo Admin > LaunchPoint > View Details. Ensure the associated API user has the necessary permissions.","cause":"Incorrect `client_id` or `client_secret` provided during `MarketoClient` initialization.","error":"Exception: unauthorized"},{"fix":"Ensure your Marketo credentials (`munchkin_id`, `client_id`, `client_secret`) are correct. The library is designed to handle token refreshing, but if you're manually managing tokens or experiencing persistent issues, review Marketo's authentication documentation for best practices on token management. If code 601 or 602 is returned by the API, the library should internally request a new token.","cause":"The authentication token used for API calls is either invalid or has expired. While the library attempts to refresh tokens, specific configurations or long-running processes might expose this.","error":"Exception: Access token invalid (code 601) or Access token expired (code 602)"},{"fix":"Upgrade the `requests` library with its security extras: `pip install requests[security]`. Ensure your Python environment and operating system's SSL certificates are up to date.","cause":"This error, particularly on macOS, can be related to issues with the `requests` library's SSL configuration or outdated system libraries.","error":"HTTP Get Exception! Retrying..... or SSLV3_ALERT_HANDSHAKE_FAILURE"},{"fix":"Always parse the JSON response and explicitly check `response.get('success')`. If `False`, iterate through `response.get('errors', [])` to understand the specific reason for the failure and handle it appropriately in your code.","cause":"The Marketo API frequently returns HTTP 200 even for failed operations, with the actual success indicated by a `success: false` field in the JSON response body, accompanied by an `errors` array.","error":"Marketo API call returns HTTP 200 OK, but no data or unexpected data is returned (success: false)"}]}