Reminder: v201611 will be sunset on November 30, 2017.

DFP Sales Manager Proposals

This guide explains 'what a proposal is' and walks you through the creation of a Proposal object via the API. It also describes what you can do once you've created your proposal.

Primer

Proposals in DFP Sales Manager represent materialized opportunities before the trafficking stage within DFP. They summarize the billing facet of an order encompassing what budget is allocated to the deal, the salespeople and traffickers assigned to manage the process, and the inventory being sold in the form of proposal line items.

Creating a proposal via the API

To create a Proposal object, the only required field is the name.

Java

  // Get the ProposalService.
  ProposalServiceInterface proposalService =
      dfpServices.get(session, ProposalServiceInterface.class);

  // Create a proposal.
  Proposal proposal = new Proposal();
  proposal.setName("Proposal #" + new Random().nextInt(Integer.MAX_VALUE));
    

Python


  # Initialize appropriate services.
  proposal_service = client.GetService('ProposalService', version='v201702')

  # Create proposal objects.
  proposal = {
      'name': 'Proposal #%s' % uuid.uuid4(),
      ...
    

PHP


    $proposalService = $dfpServices->get($session, ProposalService::class);

    // Create a proposal.
    $proposal = new Proposal();
    $proposal->setName('Proposal #' . uniqid());
    

C#


  // Get the ProposalService.
  ProposalService proposalService =
      (ProposalService) user.GetService(DfpService.v201702.ProposalService);

  // Create a proposal.
  Proposal proposal = new Proposal();
  proposal.name = "Proposal #" + new Random().Next(int.MaxValue);
    

The remainder of the fields are settings that the sales planning team can fill in afterward. As long as the fields required for trafficking are completed before submission, the proposal can be worked on in stages. The minimum required fields for submission would be to associate the proposal with an advertiser

Java


  // Create a proposal company association.
  ProposalCompanyAssociation proposalCompanyAssociation = new ProposalCompanyAssociation();
  proposalCompanyAssociation.setCompanyId(advertiserId);
  proposalCompanyAssociation.setType(ProposalCompanyAssociationType.ADVERTISER);
  proposal.setAdvertiser(proposalCompanyAssociation);
    

Python


      ...
      'advertiser': {
          'companyId': advertiser_id,
          'type': 'ADVERTISER'
      },
      ...
    

PHP


    // Create a proposal company association.
    $proposalCompanyAssociation = new ProposalCompanyAssociation();
    $proposalCompanyAssociation->setCompanyId($advertiserId);
    $proposalCompanyAssociation
        ->setType(ProposalCompanyAssociationType::ADVERTISER);
    $proposal->setAdvertiser($proposalCompanyAssociation);
    

C#


  // Create a proposal company association.
  ProposalCompanyAssociation proposalCompanyAssociation = new ProposalCompanyAssociation();
  proposalCompanyAssociation.companyId = advertiserId;
  proposalCompanyAssociation.type = ProposalCompanyAssociationType.ADVERTISER;
  proposal.advertiser = proposalCompanyAssociation;
    

If the company associated with the proposal has any contacts to attach, this would be accomplished by setting a list of IDs on the proposalCompanyAssociation object:

Java


  proposalCompanyAssociation.setContactIds(new long[] {INSERT_YOUR_LIST_OF_CONTACTS_HERE});
  proposal.setAdvertiser(proposalCompanyAssociation);
    

Python

      ...
      'advertiser': {
          'companyId': advertiser_id,
          'type': 'ADVERTISER',
          'contactIds': [INSERT_YOUR_LIST_OF_CONTACTS_HERE]
      },
      ...
    

PHP


  $proposalCompanyAssociation->contactIds = array(INSERT_YOUR_LIST_OF_CONTACTS_HERE);
  $proposal->advertiser = $proposalCompanyAssociation;
    

C#


  proposalCompanyAssociation.contactIds = new long[] {INSERT_YOUR_LIST_OF_CONTACTS_HERE};
  proposal.advertiser = proposalCompanyAssociation;
    

The primary salesperson is required before pushing to DFP - the secondary salespeople are optional. To assign a salesperson, create a SalespersonSplit object, which allows the user ID of the salesperson to be set as well as their split percentage. The same would be done with each of the secondary salespeople. Once this is done, the primary salesperson and the secondary salespeople can be associated directly on the proposal through the SalespersonSplit objects.

Java


  // Create salesperson splits for the primary salesperson and secondary salespeople.
  SalespersonSplit primarySalesperson = new SalespersonSplit();
  primarySalesperson.setUserId(primarySalespersonId);
  primarySalesperson.setSplit(75000);
  proposal.setPrimarySalesperson(primarySalesperson);
  
  SalespersonSplit secondarySalesperson = new SalespersonSplit();
  secondarySalesperson.setUserId(secondarySalespersonId);
  secondarySalesperson.setSplit(25000);    
  proposal.setSecondarySalespeople(new SalespersonSplit[] {secondarySalesperson});
    

Python


      ...
      'primarySalesperson': {
          'userId': primary_salesperson_id,
          'split': '75000'
      },
      'secondarySalespeople': [{
          'userId': secondary_salesperson_id,
          'split': '25000'
      }],
      ...
    

PHP


    // Create salesperson splits for the primary salesperson and secondary
    // salespeople.
    $primarySalesperson = new SalespersonSplit();
    $primarySalesperson->setUserId($primarySalespersonId);
    $primarySalesperson->setSplit(75000);
    $proposal->setPrimarySalesperson($primarySalesperson);

    $secondarySalesperson = new SalespersonSplit();
    $secondarySalesperson->setUserId($secondarySalespersonId);
    $secondarySalesperson->setSplit(25000);
    $proposal->setSecondarySalespeople([$secondarySalesperson]);
    

C#


  // Create salesperson splits for the primary salesperson and secondary salespeople.
  SalespersonSplit primarySalesperson = new SalespersonSplit();
  primarySalesperson.userId = primarySalespersonId;
  primarySalesperson.split = 75000;
  proposal.primarySalesperson = primarySalesperson;

  SalespersonSplit secondarySalesperson = new SalespersonSplit();
  secondarySalesperson.userId = secondarySalespersonId;
  secondarySalesperson.split = 25000;
  proposal.secondarySalespeople = new SalespersonSplit[] {secondarySalesperson};
    

The Proposal object also contains the probabilityOfClose() field which is to be entered as a millipercent amount. This field is used for calculation of revenue in reporting and can also be used as validation in workflows.

Java


  // Set the probability to close to 100%.
  proposal.setProbabilityOfClose(100000L);
    

Python


      ...
      'probabilityOfClose': '100000',
      ...
    

PHP


    // Set the probability to close to 100%.
    $proposal->setProbabilityOfClose(100000);
    

C#


  // Set the probability to close to 100%.
  proposal.probabilityOfClose = 100000L;
    

To submit a proposal a primary trafficker must be set.

Java


  // Set the primary trafficker on the proposal for when it becomes an order.
  proposal.setPrimaryTraffickerId(primaryTraffickerId);
    

Python


      ...
      'primaryTraffickerId': primary_trafficker_id,
      ...
    

PHP


    // Set the primary trafficker on the proposal for when it becomes an order.
    $proposal->setPrimaryTraffickerId($primaryTraffickerId);
    

C#


  // Set the primary trafficker on the proposal for when it becomes an order.
  proposal.primaryTraffickerId = primaryTraffickerId;
    

The proposal must also have a budget allocated to it. This is done by creating a Money object, which requires the micro-amount, a currency code (which is required and should match the currency to be used on the proposal setting).

Java


  // Create a budget for the proposal worth 100 in the network local currency.
  Money budget = new Money();
  budget.setMicroAmount(100000000L);
  budget.setCurrencyCode(networkService.getCurrentNetwork().getCurrencyCode());
  proposal.setBudget(budget);
    

Python


      ...
      'budget': {
          'microAmount': '100000000',
          'currencyCode': network_service.getCurrentNetwork()['currencyCode']
      },
      ...
    

PHP


    // Create a budget for the proposal worth 100 in the network local currency.
    $budget = new Money();
    $budget->setMicroAmount(100000000);
    $budget->setCurrencyCode(
        $networkService->getCurrentNetwork()->getCurrencyCode());
    $proposal->setBudget($budget);
    

C#


  // Create a budget for the proposal worth 100 in the network local currency.
  Money budget = new Money();
  budget.microAmount = 100000000L;
  budget.currencyCode = networkService.getCurrentNetwork().currencyCode;
  proposal.budget = budget;
    

The billing fields specify how to bill the impressions served, and what delivery numbers to use when making these calculations. They are both optional and have defaults.

Java


  proposal.setBillingCap(BillingCap.CAPPED_CUMULATIVE);
  proposal.setBillingSource(BillingSource.DFP_VOLUME);
    

Python


      ...
      'billingCap': 'CAPPED_CUMULATIVE',
      'billingSource': 'DFP_VOLUME'
      ...
    

PHP


    $proposal->setBillingCap(BillingCap::CAPPED_CUMULATIVE);
    $proposal->setBillingSource(BillingSource::DFP_VOLUME);
    

C#


  proposal.billingCap = BillingCap.CAPPED_CUMULATIVE;
  proposal.billingSource = BillingSource.DFP_VOLUME;
    

Once these fields have been set, creating new Proposal objects is done by invoking createProposals on an array of proposal objects:

Java


  // Create the proposal on the server.
  Proposal[] proposals = proposalService.createProposals(new Proposal[] {proposal});
    

Python


  # Add proposals.
  proposals = proposal_service.createProposals([proposal])
    

PHP


    // Create the proposals on the server.
    $proposals = $proposalService->createProposals([$proposal]);
    

C#


  // Create the proposal on the server.
  Proposal[] proposals = proposalService.createProposals(new Proposal[] {proposal});
    

Since proposals are generally comprised of ProposalLineItem objects, the next step would be to add proposal line items beneath your newly created proposal. Once these have been added, you can submit your proposal for approval.

Programmatic

The programmatic proposal is where the interaction between you and the buyer takes place. The buyer is specified by setting the ProposalMarketplaceInfo.buyerAccountId field. Valid buyer IDs are obtained using the Programmatic_Buyer PQL table. Most of the other fields on ProposalMarketplaceInfo are read-only and can be used to determine the state of a programmatic proposal and which actions are applicable.

States of a programmatic proposal

The states of a programmatic proposal differ slightly depending on if you're using sales management or not. The DFP help center has a good high-level overview of this for programmatic with sales management and programmatic without sales management.

The following figures depict a programmatic proposal at various points during the negotiation process from an API standpoint. Each state is represented by various combinations of the following fields:

The states a programmatic proposal, when using sales management, can
           be in during its interaction with Marketplace.
Figure 1: States of a programmatic proposal when using sales management.
The states a programmatic proposal, when not using sales management,
           can be in during its interaction with Marketplace.
Figure 2: States of a programmatic proposal when not using sales management.

Negotiation walkthrough

Here, we'll walk you through using the API to complete a negotiation for a programmatic proposal with a buyer. We'll reference the states in the diagrams above.

Preparing for buyer acceptance

Regardless of whether you're using sales management or not, you first need to draft a programmatic proposal with proposal line items that you want to send to a buyer. This is state C in both figures above.

If you're not using sales management, skip to the Requesting buyer acceptance step. Otherwise, you will need to go through the internal workflow associated with the proposal (state C to D in Figure 1). You can do this by calling SubmitProposalsForApproval.

Requesting buyer acceptance

Once you're ready to have the buyer review the programmatic proposal, you can request buyer acceptance by using the action RequestBuyerAcceptance. This will bring you into the negotiation phase.

Negotiation

In this phase, a number of things may happen.

  • The buyer may accept your programmatic proposal without changes.
  • The buyer may propose changes. In this case, the proposal will be sent back to a draft state (state B in both figures). You will then need to open the proposal for edit, make the proposed changes, and send it back for the buyer's review.
  • You may also decide to make changes even before the buyer replies. If you're using sales management, you can do this by performing the RetractProposals action. This will bring your proposal back into state B in Figure 1 where you may open the proposal for edit to make changes before sending it back to the buyer. For non-sales management, you can do this by opening the proposal for edit directly from state D in Figure 2.

This negotiation continues until you reach an agreement with the buyer. Comments between you and the buyer can be retrieved using getMarketplaceCommentsByStatement You can send a comment to the buyer while in state A (on both figures). To do this, you will need to update the marketplaceComment field on the proposal using updateProposals. The comment will then be sent when you request buyer acceptance.

Finalized

When both you and the buyer have both accepted the programmatic proposal, it goes into a finalized state (state E in Figure 1 and state F in Figure 2). DFP then automatically creates line items from this programmatic proposal.

In most cases you are now done with the programmatic proposal. But there are two actions you can perform from this state:

  • You may re-open the programmatic proposal for renegotiation by editing serving-related fields on the proposal. If you're using sales management, you can do this by retracting the proposal (state F to B in Figure 1), opening it for edit, making changes, submitting it through internal workflow, and then requesting buyer acceptance. For non-sales management users, you can do this by opening the proposal for edit (state E to A in Figure 2), making changes, and then requesting buyer acceptance.
  • You may make non-serving related edits, such as updating the proposal's name, and reflecting these changes in the DFP order and line items created from this deal. If you're using sales management, you can do this by retracting from state F in Figure 1, editing, and submitting through internal workflow. This will bring you to state G in Figure 1, where you then perform the action UpdateOrderWithSellerData, For non-sales management users, you can do this by editing the from state E in Figure 2 and then performing the UpdateOrderWithSellerData action.

Send feedback about...

DoubleClick for Publishers
DoubleClick for Publishers
Need help? Visit our support page.