Portfolios

Warning

Retired on 1 March 2025. All six /v2/portfolios routes answer 404 Method Not Found: the service no longer routes them, whatever the account or the token. The code stays for anyone pinning an old release, but it cannot reach the API.

Use PortfoliosV3 instead. The field names and the date format changed between the two versions, so a body that worked here does not work there.

Portfolios consist of campaigns that are grouped together and linked to a distinct Advertiser Account. The term ‘advertiser’ refers to a brand, entity, account identifier, or claim identifier. Multiple portfolios are supported within an Advertiser Account.

class ad_api.api.Portfolios(account: str = 'default', marketplace: Marketplaces = Marketplaces.EU, credentials: Dict[str, str] | None = None, proxies: Dict[str, str] | None = None, verify: bool = True, timeout: int | None = None, debug: bool = False, access_token: str | None = None, verify_additional_credentials: bool = True)

Note

This API Portfolios can be used as sandbox environment for testing

### Example listing portfolios

import logging
from ad_api.api import Portfolios
from ad_api.base import AdvertisingApiException

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s:%(levelname)s:%(message)s"
)

def list_portfolios(**kwargs):
    try:
        result = Portfolios(debug=True).list_portfolios(
            **kwargs
        )

        if result.payload:
            payload = result.payload
            for portfolio in payload:
                logging.info(portfolio)
        else:
            logging.info(result)

    except AdvertisingApiException as error:
        logging.info(error)

if __name__ == '__main__':

    # list_portfolios()
    # list_portfolios(portfolioStateFilter="enabled")
    list_portfolios(portfolioIdFilter="84653842194444,183826157455614,92453628442009,31260007270996")
    # list_portfolios(portfolioNameFilter="Apple,Huawei,Sony")

### Example listing portfolios extended

import logging
from ad_api.api import Portfolios
from ad_api.base import AdvertisingApiException

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s:%(levelname)s:%(message)s"
)

def list_portfolios_extended(**kwargs):
    try:
        result = Portfolios(debug=True).list_portfolios_extended(
            **kwargs
        )

        if result.payload:
            payload = result.payload
            for portfolio in payload:
                logging.info(portfolio)
        else:
            logging.info(result)

    except AdvertisingApiException as error:
        logging.info(error)

if __name__ == '__main__':

    # list_portfolios_extended()
    # list_portfolios_extended(portfolioStateFilter="enabled")
    list_portfolios_extended(portfolioIdFilter="84653842194444,183826157455614,92453628442009,31260007270996")
    # list_portfolios_extended(portfolioNameFilter="Apple,Huawei,Sony")

### Example getting a portfolio by portfolioId

import logging
from ad_api.api import Portfolios
from ad_api.base import AdvertisingApiException

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s:%(levelname)s:%(message)s"
)

def get_portfolio(portfolio_id: int):
    try:
        result = Portfolios(debug=True).get_portfolio(
            portfolioId=portfolio_id
        )
        payload = result.payload
        logging.info(payload)

    except AdvertisingApiException as error:
        logging.info(error)

if __name__ == '__main__':

    id_portfolio = 214026257044134
    get_portfolio(id_portfolio)

### Example getting a portfolio extended by portfolioId

import logging
from ad_api.api import Portfolios
from ad_api.base import AdvertisingApiException

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s:%(levelname)s:%(message)s"
)

def get_portfolio_extended(portfolio_id: int):
    try:
        result = Portfolios(debug=True).get_portfolio_extended(
            portfolioId=portfolio_id
        )
        payload = result.payload
        logging.info(payload)

    except AdvertisingApiException as error:
        logging.info(error)

if __name__ == '__main__':

    id_portfolio = 214026257044134
    get_portfolio_extended(id_portfolio)

### Example creating a portfolio from a list or from a dict

import logging
from ad_api.api import Portfolios
from ad_api.base import AdvertisingApiException

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s:%(levelname)s:%(message)s"
)

def create_portfolios(data: (list, str, dict)):
    try:
        result = Portfolios(debug=True).create_portfolios(
            body=data
        )

        logging.info(result)

    except AdvertisingApiException as error:
        logging.info(error)

if __name__ == '__main__':

    request_portfolios = \
        [
            {
                "name": "Apple",
                "budget": {
                    "amount": 100,
                    "currencyCode": "EUR",
                    "policy": "monthlyRecurring",
                    "startDate": "20220418"
                },
                "inBudget": False,
                "state": "enabled"
            },
            {
                "name": "Huawei",
                "budget": {
                    "amount": 120,
                    "currencyCode": "EUR",
                    "policy": "dateRange",
                    "startDate": "20220418"
                },
                "inBudget": False,
                "state": "enabled"
            },
            {
                "name": "Sony",
                "budget": {
                    "amount": 120,
                    "currencyCode": "EUR",
                    "policy": "dateRange",
                    "startDate": "20220418"
                },
                "inBudget": False,
                "state": "enabled"
            }
        ]

    create_single_dict_portfolio = \
        {
            "name": "Pioneer",
            "budget": {
                "amount": 44.5,
                "policy": "monthlyRecurring",
                "startDate": "20220418"
            },
            "state": "enabled"
        }

    create_portfolios(request_portfolio)
    # create_portfolios(create_single_dict_portfolio)

### Example creating a portfolio from a static json file

import logging
from ad_api.api import Portfolios
from ad_api.base import AdvertisingApiException

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s:%(levelname)s:%(message)s"
)

def create_portfolios(data: (list, str, dict)):
    try:
        result = Portfolios(debug=True).create_portfolios(
            body=data
        )

        logging.info(result)

    except AdvertisingApiException as error:
        logging.info(error)

if __name__ == '__main__':

    filename = "../test/portfolios/create.json"
    create_portfolios(filename)

# Static .json file in case want to use as example

[
    {
        "name": "Apple",
        "budget": {
            "amount": 100,
            "currencyCode": "EUR",
            "policy": "monthlyRecurring",
            "startDate": "20220418"
        },
        "inBudget": true,
        "state": "enabled"
    },
    {
        "name": "Huawei",
        "budget": {
            "amount": 120,
            "currencyCode": "EUR",
            "policy": "dateRange",
            "startDate": "20220418"
        },
        "inBudget": true,
        "state": "enabled"
    },
    {
        "name": "Sony",
        "budget": {
            "amount": 120,
            "currencyCode": "EUR",
            "policy": "dateRange",
            "startDate": "20220418"
        },
        "inBudget": true,
        "state": "enabled"
    }
]

Download json the file to use:

### Example editing a portfolio from a list or from a dict

import logging
from ad_api.api import Portfolios
from ad_api.base import AdvertisingApiException

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s:%(levelname)s:%(message)s"
)

def edit_portfolios(data: (list, str, dict)):
    try:
        result = Portfolios(debug=True).edit_portfolios(
            body=data
        )

        logging.info(result)

    except AdvertisingApiException as error:
        logging.info(error)

if __name__ == '__main__':

    update_portfolios = \
        [
            {
                "portfolioId": 183826157455614,
                "name": "Apple-Macbook",
                "budget": {
                    "amount": 77.5,
                    "currencyCode": "EUR",
                    "policy": "monthlyRecurring",
                    "startDate": "20220418"
                },
                "inBudget": False,
                "state": "enabled"
            },
            {
                "portfolioId": 84653842194444,
                "name": "Huawei-Phone",
                "budget": {
                    "amount": 25,
                    "currencyCode": "EUR",
                    "policy": "dateRange",
                    "startDate": "20220418"
                },
                "inBudget": False,
                "state": "enabled"
            },
            {
                "portfolioId": 92453628442009,
                "name": "Sony-Headphones",
                "budget": {
                    "amount": 55,
                    "currencyCode": "EUR",
                    "policy": "dateRange",
                    "startDate": "20220418"
                },
                "inBudget": False,
                "state": "enabled"
            }
        ]

    update_single_portfolio = \
        [
            {
                "portfolioId": 183826157455614,
                "name": "Apple-iMac",
                "budget": {
                    "amount": 30.5,
                    "policy": "monthlyRecurring",
                    "startDate": "20220418"
                },
                "inBudget": True,
                "state": "enabled"
            }
        ]

    update_single_dict_portfolio = \
        {
            "portfolioId": 183826157455614,
            "name": "Apple-All",
            "budget": {
                "amount": 80.5,
                "policy": "monthlyRecurring",
                "startDate": "20220418"
            },
            "inBudget": True,
            "state": "enabled"
        }

    # edit_portfolios(update_portfolios)
    # edit_portfolios(update_single_portfolio)
    edit_portfolios(update_single_dict_portfolio)

### Example editing a portfolio from a static json file

import logging
from ad_api.api import Portfolios
from ad_api.base import AdvertisingApiException

logging.basicConfig(
    level=logging.INFO,
    format="%(asctime)s:%(levelname)s:%(message)s"
)

def edit_portfolios(data: (list, str, dict)):
    try:
        result = Portfolios(debug=True).edit_portfolios(
            body=data
        )

        logging.info(result)

    except AdvertisingApiException as error:
        logging.info(error)

if __name__ == '__main__':

    filename = "../test/portfolios/edit.json"
    edit_portfolios(filename)

# Static .json file in case want to use as example

[
    {
        "portfolioId": 183826157455614,
        "name": "Apple-iMac",
        "budget": {
            "amount": 80.5,
            "policy": "monthlyRecurring",
            "startDate": "20220418"
        },
        "inBudget": true,
        "state": "enabled"
    }
]

Download json the file to use:

list_portfolios(**kwargs) → ApiResponse

Retrieves a list of portfolios, optionally filtered by identifier, name, or state. Note that this operation returns a maximum of 100 portfolios.

query portfolioIdFilter:string | Optional. The returned list includes portfolios with identifiers matching those in the specified comma-delimited list. There is a maximum of 100 identifiers allowed

query portfolioNameFilter:string | Optional. The returned list includes portfolios with identifiers matching those in the specified comma-delimited list. There is a maximum of 100 identifiers allowed

query portfolioStateFilter:string | Optional. The returned list includes portfolios with states matching those in the specified comma-delimited list. Available values : enabled, paused, archived

list_portfolios_extended(**kwargs) → ApiResponse

Retrieves a list of portfolios, optionally filtered by identifier, name, or state. Note that this operation returns a maximum of 100 portfolios.

query portfolioIdFilter:string | Optional. The returned list includes portfolios with identifiers matching those in the specified comma-delimited list. There is a maximum of 100 identifiers allowed

query portfolioNameFilter:string | Optional. The returned list includes portfolios with identifiers matching those in the specified comma-delimited list. There is a maximum of 100 identifiers allowed

query portfolioStateFilter:string | Optional. The returned list includes portfolios with states matching those in the specified comma-delimited list. Available values : enabled, paused, archived

get_portfolio(portfolioId) → ApiResponse

Retrieves a portfolio data with the portfolioId identifier provided

query portfolioId:number | Required. The identifier of an existing portfolio.

get_portfolio_extended(portfolioId) → ApiResponse

Gets an extended set of properties for a portfolio specified by identifier.

query portfolioId:number | Required. The identifier of an existing portfolio.

create_portfolios(body: list, str, dict) → ApiResponse

Creates one or more portfolios.

body: | REQUIRED {‘description’: ‘A list of portfolio resources with updated values.}’

name | string | The portfolio name.
budget | dict |
amount | number | The budget amount associated with the portfolio. Cannot be null.
currencyCode | string | The currency used for all monetary values for entities under this profile. Cannot be null.
policy | string | The budget policy. Set to dateRange to specify a budget for a specific period of time. Set to monthlyRecurring to specify a budget that is automatically renewed at the beginning of each month. Cannot be null. Enum: [ dateRange, monthlyRecurring ]
startDate | string | The starting date in YYYYMMDD format to which the budget is applied. Required if policy is set to dateRange. Not specified if policy is set to monthlyRecurring. Note that the starting date for monthlyRecurring is the date when the policy is set.
endDate | string | The end date after which the budget is no longer applied. Optional if policy is set to dateRange or monthlyRecurring.
inBudget | boolean | Indicates the current budget status of the portfolio. Set to true if the portfolio is in budget, set to false if the portfolio is out of budget.
state | string | The current state of the portfolio. Enum: [ enabled, paused, archived ]
edit_portfolios(body: list, str, dict) → ApiResponse

Updates one or more portfolios.

body: | REQUIRED {‘description’: ‘A list of portfolio resources with updated values.}’

portfolioId | number | The portfolio identifier.
name | string | The portfolio name.
budget | dict |
amount | number | The budget amount associated with the portfolio. Cannot be null.
currencyCode | string | The currency used for all monetary values for entities under this profile. Cannot be null.
policy | string | The budget policy. Set to dateRange to specify a budget for a specific period of time. Set to monthlyRecurring to specify a budget that is automatically renewed at the beginning of each month. Cannot be null. Enum: [ dateRange, monthlyRecurring ]
startDate | string | The starting date in YYYYMMDD format to which the budget is applied. Required if policy is set to dateRange. Not specified if policy is set to monthlyRecurring. Note that the starting date for monthlyRecurring is the date when the policy is set.
endDate | string | The end date after which the budget is no longer applied. Optional if policy is set to dateRange or monthlyRecurring.
inBudget | boolean | Indicates the current budget status of the portfolio. Set to true if the portfolio is in budget, set to false if the portfolio is out of budget.
state | string | The current state of the portfolio. Enum: [ enabled, paused, archived ]