BOOK A DEMO

Guides

Create Your First Auction

Create an auction with the Management API and place a bid with the Client API — using the GraphQL UIs in the browser.

This guide shows you how to create an auction using the Management API and how to bid on an item using the Client API. This guide uses the GraphQL UIs in the browser.

Prerequisites: Ensure that you have either a valid cookie in the browser or the API key and account ID headers set. See API Access.

Step 1: Create a Sale

A sale is a grouping of 1 or more items.

Sale Input Properties

  • title: Short title for the sale
  • description: Further details for the sale
  • currency: Only "USD" is supported
  • bidIncrementTable: Defines increments by which bids can increase (optional at sale level, applies to all items)
  • closingMethod: Only 'OVERLAPPING' is currently supported
  • closingTimeCountdown: Optional value that applies to all items within the sale
GraphQL
mutation CreateSale {
  createSale(accountId: "ACCOUNT_ID", input: {
    title: "Test Sale",
    description: "Description for the sale",
    currency: "USD",
    bidIncrementTable: {
      rules: [
        { lowRange: 0, highRange: 100000, step: 10000 },
        { lowRange: 100000, highRange: 500000, step: 25000 },
      ]
    }
    closingMethod: OVERLAPPING,
    closingTimeCountdown: 60000
  }) {
    id
    status
  }
}

Response

JSON
{
  "data": {
    "createSale": {
      "id": "GENERATED_SALE_ID",
      "status": "UNPUBLISHED"
    }
  }
}

Step 2: Create an Item

Create a standalone item that can be added to sales.

Item Input Properties

  • title: Title for the item
  • description: Description for the item
  • tags: Optional tags for categorization
GraphQL
mutation CreateItem {
  createItem(accountId: "ACCOUNT_ID", input: {
    title: "David Gilmour's 1969 Stratocaster"
    description: "David Gilmour purchased the guitar, a 1969 model with a maple cap fingerboard and large headstock, in 1970 from Manny's Music in New York City to replace a similar guitar his parents bought him for his 21st birthday, which had been lost while touring with Pink Floyd in the United States in 1968. The Black Strat was originally a sunburst colour, but had been repainted black at Manny's. Since then, it has undergone numerous modifications."
    tags: ["guitars", "vintage", "pink-floyd"]
  }) {
    id
    title
    description
  }
}

Response

JSON
{
  "data": {
    "createItem": {
      "id": "GENERATED_ITEM_ID",
      "title": "David Gilmour's 1969 Stratocaster",
      "description": "David Gilmour purchased the guitar..."
    }
  }
}

Step 3: Add Item to Sale

Add the previously created item to the sale with auction-specific settings.

AddItemToSale Input Properties

  • saleId: The sale ID to add the item to
  • itemId: The item ID from the previous step
  • startingBid: Minimum first bid (1000 cents = $10)
  • reserve: Minimum selling price (200000000 cents = $2,000,000)
  • allowedBidTypes: Bid types allowed (e.g., MAX, NORMAL)
  • openDate: When bidding opens (RFC3339 timestamp)
  • closingDate: When item moves to closing status (RFC3339 timestamp)
GraphQL
mutation AddItemToSale {
  addItemToSale(accountId: "ACCOUNT_ID", input: {
    saleId: "GENERATED_SALE_ID"
    itemId: "GENERATED_ITEM_ID"
    startingBid: 1000
    reserve: 200000000
    allowedBidTypes: [MAX]
    openDate: "2024-02-01T15:00:00Z"
    closingDate: "2024-02-01T16:00:00Z"
  }) {
    id
    dates {
      openDate
      closingStart
      closingEnd
    }
    status
  }
}

Response

JSON
{
  "data": {
    "addItemToSale": {
      "id": "GENERATED_ITEM_ID",
      "dates": {
        "openDate": "2024-02-01T15:00:00Z",
        "closingStart": "2024-02-01T16:00:00Z",
        "closingEnd": "2024-02-01T16:01:00Z"
      },
      "status": "ITEM_NOT_OPEN"
    }
  }
}

Step 4: Publish Sale

After a sale is created and items have been added, it is initially in status UNPUBLISHED.

If the sale should go live, it needs to be published. After a sale has been published, Basta will manage the lifecycle of the sale and handle opening and closing of the sale and its items.

GraphQL
mutation PublishSale {
  publishSale(accountId: "ACCOUNT_ID", input: {
    saleId: "GENERATED_SALE_ID"
  }) {
    id
    status
  }
}

Response

JSON
{
  "data": {
    "publishSale": {
      "id": "GENERATED_SALE_ID",
      "status": "PUBLISHED"
    }
  }
}

Step 5: Get Sale

Verify your sale was created successfully:

GraphQL
query GetSale {
  sale(accountId: "ACCOUNT_ID", id: "GENERATED_SALE_ID") {
    id
    status
    items {
      edges {
        node {
          id
          dates {
            openDate
            closingStart
            closingEnd
          }
        }
      }
    }
  }
}

Response

JSON
{
  "data": {
    "sale": {
      "id": "GENERATED_SALE_ID",
      "status": "PUBLISHED",
      "items": {
        "edges": [
          {
            "node": {
              "id": "GENERATED_ITEM_ID",
              "dates": {
                "openDate": "2024-02-01T15:00:00Z",
                "closingStart": "2024-02-01T16:00:00Z",
                "closingEnd": "2024-02-01T16:01:00Z"
              }
            }
          }
        ]
      }
    }
  }
}

Step 6: Create Bidder Token

The owner of a sale must create a bidder token for each bidder, typically after bidder verification. A bid can only be executed if an authorization header with the corresponding bidder token is present.

BidderToken Input Parameters

  • userId: The userId of the bidder
  • ttl: Time to live for the bidder token in minutes
GraphQL
mutation CreateBidderToken($accountID: String!) {
  createBidderToken(accountId: $accountID, input: {
    metadata: {
      userId: "user-1",
      ttl: 60
    }
  }) {
    token
    expiration
  }
}

Response

JSON
{
  "data": {
    "createBidderToken": {
      "token": "GENERATED_BIDDER_TOKEN",
      "expiration": "2023-04-19T17:20:10Z"
    }
  }
}

Step 7: Place a Bid (Client API)

Now switch to the Client API to place a bid.

Important: Set Authorization Header

To execute a bid, an Authorization header must be present:

JSON
{
  "Authorization": "Bearer GENERATED_BIDDER_TOKEN"
}

BidOnItem Mutation

GraphQL
mutation MaxBid {
  bidOnItem(
    saleId: "GENERATED_SALE_ID",
    itemId: "GENERATED_ITEM_ID",
    amount: 10000,
    type: MAX
  ) {
    __typename
    ...on BidPlacedSuccess {
      amount
      bidStatus
      date
      bidType
    }
    ...on BidPlacedError {
      errorCode
      error
    }
  }
}

Response

JSON
{
  "data": {
    "bidOnItem": {
      "__typename": "BidPlacedSuccess",
      "amount": 10000,
      "bidStatus": "WINNING",
      "date": "2024-02-01T15:30:00Z",
      "bidType": "MAX"
    }
  }
}

Complete Code Example

Here's a complete Node.js/TypeScript example:

TypeScript
import fetch from 'node-fetch';

const MANAGEMENT_API = 'https://management-api.basta.app/graphql';
const CLIENT_API = 'https://client.api.basta.app/graphql';
const ACCOUNT_ID = process.env.BASTA_ACCOUNT_ID;
const API_KEY = process.env.BASTA_API_KEY;

// Helper function for Management API calls
async function managementApiCall(query: string, variables = {}) {
  const response = await fetch(MANAGEMENT_API, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'x-account-id': ACCOUNT_ID,
      'x-api-key': API_KEY
    },
    body: JSON.stringify({ query, variables })
  });
  return response.json();
}

// Helper function for Client API calls
async function clientApiCall(query: string, variables = {}, bidderToken?: string) {
  const headers: any = {
    'Content-Type': 'application/json'
  };
  if (bidderToken) {
    headers['Authorization'] = `Bearer ${bidderToken}`;
  }

  const response = await fetch(CLIENT_API, {
    method: 'POST',
    headers,
    body: JSON.stringify({ query, variables })
  });
  return response.json();
}

async function createFirstAuction() {
  // 1. Create Sale
  const saleResult = await managementApiCall(`
    mutation CreateSale($accountId: String!) {
      createSale(accountId: $accountId, input: {
        title: "Test Sale",
        description: "My first auction",
        currency: "USD",
        closingMethod: OVERLAPPING,
        closingTimeCountdown: 60000
      }) {
        id
        status
      }
    }
  `, { accountId: ACCOUNT_ID });

  const saleId = saleResult.data.createSale.id;
  console.log('Sale created:', saleId);

  // 2. Create Item
  const itemResult = await managementApiCall(`
    mutation CreateItem($accountId: String!) {
      createItem(accountId: $accountId, input: {
        title: "Test Item",
        description: "A test item for auction",
        tags: ["test", "demo"]
      }) {
        id
      }
    }
  `, { accountId: ACCOUNT_ID });

  const itemId = itemResult.data.createItem.id;
  console.log('Item created:', itemId);

  // 3. Add Item to Sale
  await managementApiCall(`
    mutation AddItemToSale($accountId: String!, $saleId: ID!, $itemId: ID!) {
      addItemToSale(accountId: $accountId, input: {
        saleId: $saleId,
        itemId: $itemId,
        startingBid: 1000,
        reserve: 10000,
        allowedBidTypes: [MAX],
        openDate: "${new Date(Date.now() + 60000).toISOString()}",
        closingDate: "${new Date(Date.now() + 3600000).toISOString()}"
      }) {
        id
      }
    }
  `, { accountId: ACCOUNT_ID, saleId, itemId });

  console.log('Item added to sale');

  // 4. Publish Sale
  await managementApiCall(`
    mutation PublishSale($accountId: String!, $saleId: ID!) {
      publishSale(accountId: $accountId, input: {
        saleId: $saleId
      }) {
        id
        status
      }
    }
  `, { accountId: ACCOUNT_ID, saleId });

  console.log('Sale published');

  // 5. Create Bidder Token
  const tokenResult = await managementApiCall(`
    mutation CreateBidderToken($accountId: String!) {
      createBidderToken(accountId: $accountId, input: {
        metadata: {
          userId: "user-1",
          ttl: 60
        }
      }) {
        token
        expiration
      }
    }
  `, { accountId: ACCOUNT_ID });

  const bidderToken = tokenResult.data.createBidderToken.token;
  console.log('Bidder token created');

  // 6. Place Bid (wait for sale to open)
  await new Promise(resolve => setTimeout(resolve, 65000)); // Wait for sale to open

  const bidResult = await clientApiCall(`
    mutation BidOnItem($saleId: ID!, $itemId: ID!, $amount: Int!) {
      bidOnItem(saleId: $saleId, itemId: $itemId, amount: $amount, type: MAX) {
        __typename
        ...on BidPlacedSuccess {
          amount
          bidStatus
        }
      }
    }
  `, { saleId, itemId, amount: 5000 }, bidderToken);

  console.log('Bid placed:', bidResult.data.bidOnItem);
}

createFirstAuction().catch(console.error);

Next Steps

Support

Need help? Contact us at hi@basta.app.