Accept or cancel proposals

  • The buyers.proposals.accept method allows you to approve a proposal and its associated deals for your buyer account or clients.

  • You can only accept a proposal after the publisher has accepted it; attempting to accept before the publisher will result in an error.

  • Once both parties accept a proposal, its state changes to FINALIZED, and its deals become eligible to serve.

  • The buyers.proposals.cancelNegotiation method cancels ongoing negotiation for a proposal, setting its state to TERMINATED if never finalized, or reverting to the last finalized revision if previously finalized.

  • You cannot cancel private auction deals using the Marketplace API; they can only be archived in the Authorized Buyers Marketplace UI.

You can use the following methods to accept or cancel proposals for your buyer account and any of your clients.

Accept proposal

You can use buyers.proposals.accept to approve a given proposal and its associated deals at the specified proposalRevision.

Buyers can only accept a proposal after the proposal is accepted by the publisher. If you accept a proposal before the publisher, buyers.proposals.accept returns an error.

If both parties accept a proposal, the proposal’s state is FINALIZED, and the proposal's deals become eligible to start serving based on their configurations.

The following sample demonstrates how you can accept a proposal with the accept method.

REST

Request

POST https://authorizedbuyersmarketplace.googleapis.com/v1/buyers/12345678/proposals/MP48576074:accept?alt=json
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json

{
 "proposalRevision": "4"
}

Response

{
 "name": "buyers/12345678/proposals/MP49876074",
 "updateTime": "2022-03-26T04:03:19.282Z",
 "proposalRevision": "5",
 "dealType": "PROGRAMMATIC_GUARANTEED",
 "displayName": "Test PG Proposal #0ce643e9-5518-4e8e-b352-0cb45cc2eeb2",
 "state": "FINALIZED",
 "originatorRole": "BUYER",
 "publisherProfile": "buyers/12345678/publisherProfiles/PP111111",
 "buyer": "buyers/12345678",
 "buyerPrivateData": {
   "referenceId": "2f5e9550-8d22-495e-ba38-9b9496347a3b"
 },
 "billedBuyer": "buyers/12345678",
 "sellerContacts": [
   {
     "email": "jeff@hypersonicmedia.com"
   },
   {
     "email": "alex@hypersonicmedia.com"
   },
 ],
 "buyerContacts": [
   {
     "email": "testemail89319783@test.com",
     "displayName": "Joe"
   }
 ],
 "lastUpdaterOrCommentorRole": "BUYER",
 "pausingConsented": true,
 "notes": [
   {
     "createTime": "2022-03-26T04:03:19.548Z",
     "creatorRole": "BUYER",
     "note": "Test programmatic guaranteed deal proposal."
   },
   {
     "createTime": "2022-03-26T05:36:23.406Z",
     "creatorRole": "BUYER",
     "note": "Test note."
   }
 ]
}

Java

/*
 * Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.api.services.samples.authorizedbuyers.marketplace.v1.buyers.proposals;

import com.google.api.services.authorizedbuyersmarketplace.v1.AuthorizedBuyersMarketplace;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.AcceptProposalRequest;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.Proposal;
import com.google.api.services.samples.authorizedbuyers.marketplace.v1.Utils;
import java.io.IOException;
import java.security.GeneralSecurityException;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;

/**
 * Accepts a proposal for the given account and proposal IDs.
 *
 * <p>Note that a proposal can only be accepted if it is in the BUYER_ACCEPTANCE_REQUESTED state.
 * Once both a buyer and seller have accepted a proposal, its state will change to FINALIZED.
 */
public class AcceptProposals {

  public static void execute(AuthorizedBuyersMarketplace marketplaceClient, Namespace parsedArgs) {
    Long accountId = parsedArgs.getLong("account_id");
    String proposalId = parsedArgs.getString("proposal_id");
    String name = String.format("buyers/%d/proposals/%s", accountId, proposalId);

    AcceptProposalRequest acceptProposalRequest = new AcceptProposalRequest();
    acceptProposalRequest.setProposalRevision(parsedArgs.getLong("proposal_revision"));

    Proposal proposal = null;

    try {
      proposal =
          marketplaceClient.buyers().proposals().accept(name, acceptProposalRequest).execute();
    } catch (IOException ex) {
      System.out.printf("Marketplace API returned error response:%n%s", ex);
      System.exit(1);
    }

    System.out.printf("Accepting proposal with name \"%s\":%n", name);
    Utils.printProposal(proposal);
  }

  public static void main(String[] args) {
    ArgumentParser parser =
        ArgumentParsers.newFor("AcceptProposals")
            .build()
            .defaultHelp(true)
            .description(("Accepts a proposal for the given account and proposal IDs."));
    parser
        .addArgument("-a", "--account_id")
        .help(
            "The resource ID of the buyers resource under which the proposal exists. This will "
                + "be used to construct the name used as a path parameter for the proposals.accept "
                + "request.")
        .required(true)
        .type(Long.class);
    parser
        .addArgument("-p", "--proposal_id")
        .help(
            "The resource ID of the buyers.proposals resource that is being accepted. This "
                + "will be used to construct the name used as a path parameter for the "
                + "proposals.accept request.")
        .required(true);
    parser
        .addArgument("-r", "--proposal_revision")
        .help(
            "The last known revision number of the proposal. If this is less than the "
                + "revision number stored server-side, it means that the proposal revision being "
                + "worked upon is obsolete, and an error message will be returned.")
        .required(true)
        .type(Long.class);

    Namespace parsedArgs = null;
    try {
      parsedArgs = parser.parseArgs(args);
    } catch (ArgumentParserException ex) {
      parser.handleError(ex);
      System.exit(1);
    }

    AuthorizedBuyersMarketplace client = null;
    try {
      client = Utils.getMarketplaceClient();
    } catch (IOException ex) {
      System.out.printf("Unable to create Marketplace API service:%n%s", ex);
      System.out.println("Did you specify a valid path to a service account key file?");
      System.exit(1);
    } catch (GeneralSecurityException ex) {
      System.out.printf("Unable to establish secure HttpTransport:%n%s", ex);
      System.exit(1);
    }

    execute(client, parsedArgs);
  }
}

Cancel negotiation

You can use the buyers.proposals.cancelNegotiation method to cancel negotiation for a given proposal.

If you cancel a proposal that has never been finalized, its state is set to TERMINATED, and negotiation with the publisher ends. If you cancel a proposal that has a previously finalized proposalRevision, the proposal reverts to the last finalized proposalRevision instead of being terminated.

You can't cancel private auction deals with the Marketplace API. You can archive private auction deals in the Authorized Buyers Marketplace UI.

The following sample demonstrates how you can cancel negotiation for a proposal with the cancelNegotiation method.

REST

Request

POST https://authorizedbuyersmarketplace.googleapis.com/v1/buyers/12345678/proposals/MP14138120:cancelNegotiation?alt=json
Authorization: Bearer ACCESS_TOKEN
Content-Type: application/json

Response

{
 "name": "buyers/12345678/proposals/MP14138120",
 "updateTime": "2022-03-20T03:08:36.424Z",
 "proposalRevision": "2",
 "dealType": "PROGRAMMATIC_GUARANTEED",
 "displayName": "Test PG Proposal 3",
 "state": "TERMINATED",
 "originatorRole": "BUYER",
 "publisherProfile": "buyers/12345678/publisherProfiles/PP892146",
 "buyer": "buyers/12345678",
 "billedBuyer": "buyers/12345678",
 "sellerContacts": [
   {
     "email": "cindy@garb.com"
   }
 ],
 "buyerContacts": [
   {
     "email": "testemail2022@gmail.com"
   }
 ],
 "lastUpdaterOrCommentorRole": "BUYER",
 "notes": [
   {
     "createTime": "2022-03-20T03:08:36.424Z",
     "creatorRole": "BUYER",
     "note": "Verified that ad sizes are supported."
   }
 ]
}   

Java

/*
 * Copyright 2022 Google LLC
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *    https://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.google.api.services.samples.authorizedbuyers.marketplace.v1.buyers.proposals;

import com.google.api.services.authorizedbuyersmarketplace.v1.AuthorizedBuyersMarketplace;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.CancelNegotiationRequest;
import com.google.api.services.authorizedbuyersmarketplace.v1.model.Proposal;
import com.google.api.services.samples.authorizedbuyers.marketplace.v1.Utils;
import java.io.IOException;
import java.security.GeneralSecurityException;
import net.sourceforge.argparse4j.ArgumentParsers;
import net.sourceforge.argparse4j.inf.ArgumentParser;
import net.sourceforge.argparse4j.inf.ArgumentParserException;
import net.sourceforge.argparse4j.inf.Namespace;

/**
 * Cancels the ongoing negotiation for the specified proposal.
 *
 * <p>This method is not supported for proposals including private auction deals because negotiation
 * for that deal type can not be canceled. On successful cancelation, the proposal's state will be
 * set to TERMINATED.
 *
 * <p>This does not cancel or end serving for deals that have already been finalized. For finalized
 * deals that are under renegotiation, calling this method will instead reset the proposal's state
 * to FINALIZED.
 */
public class CancelNegotiationForProposals {

  public static void execute(AuthorizedBuyersMarketplace marketplaceClient, Namespace parsedArgs) {
    Long accountId = parsedArgs.getLong("account_id");
    String proposalId = parsedArgs.getString("proposal_id");
    String name = String.format("buyers/%d/proposals/%s", accountId, proposalId);

    CancelNegotiationRequest cancelNegotiationRequest = new CancelNegotiationRequest();

    Proposal proposal = null;

    try {
      proposal =
          marketplaceClient
              .buyers()
              .proposals()
              .cancelNegotiation(name, cancelNegotiationRequest)
              .execute();
    } catch (IOException ex) {
      System.out.printf("Marketplace API returned error response:%n%s", ex);
      System.exit(1);
    }

    System.out.printf("Canceling negotiation for a proposal with name \"%s\":%n", name);
    Utils.printProposal(proposal);
  }

  public static void main(String[] args) {
    ArgumentParser parser =
        ArgumentParsers.newFor("CancelNegotiationForProposals")
            .build()
            .defaultHelp(true)
            .description(
                ("Cancels negotiation for a proposal with the given account and proposal "
                    + "IDs."));
    parser
        .addArgument("-a", "--account_id")
        .help(
            "The resource ID of the buyers resource under which the proposal exists. This will "
                + "be used to construct the name used as a path parameter for the "
                + "proposals.cancelNegotiaton request.")
        .required(true)
        .type(Long.class);
    parser
        .addArgument("-p", "--proposal_id")
        .help(
            "The resource ID of the buyers.proposals resource that is being canceled. This "
                + "will be used to construct the name used as a path parameter for the "
                + "proposals.cancelNegotiation request.")
        .required(true);

    Namespace parsedArgs = null;
    try {
      parsedArgs = parser.parseArgs(args);
    } catch (ArgumentParserException ex) {
      parser.handleError(ex);
      System.exit(1);
    }

    AuthorizedBuyersMarketplace client = null;
    try {
      client = Utils.getMarketplaceClient();
    } catch (IOException ex) {
      System.out.printf("Unable to create Marketplace API service:%n%s", ex);
      System.out.println("Did you specify a valid path to a service account key file?");
      System.exit(1);
    } catch (GeneralSecurityException ex) {
      System.out.printf("Unable to establish secure HttpTransport:%n%s", ex);
      System.exit(1);
    }

    execute(client, parsedArgs);
  }
}