Making Your First Query

Getting Started

Prerequisites

Before you begin, ensure you have:

Your First Query

Let's start with a simple query to fetch products from your inventory.

Query Structure

query {
  productViewConnection(first: 5) {
    edges {
      node {
        productId
        description
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

Understanding the Query

  • productViewConnection: The query name for accessing products
  • first: 5: Fetch the first 5 products
  • edges: Wrapper for result items (Relay pattern)
  • node: The actual product data
  • pageInfo: Pagination metadata

Making the Request

curl -X POST "https://app.finaleinventory.com/youraccount/api/graphql" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic YOUR_BASE64_ENCODED_CREDENTIALS" \
  -d '{
    "query": "query { productViewConnection(first: 5) { edges { node { productId description } } pageInfo { hasNextPage endCursor } } }"
  }'

Expected Response

{
  "data": {
    "productViewConnection": {
      "edges": [
        {
          "node": {
            "productId": "000-IMG-001",
            "description": "Product with a random image"
          }
        },
        {
          "node": {
            "productId": "000-IMG-002",
            "description": "Product with random image"
          }
        }
      ],
      "pageInfo": {
        "hasNextPage": true,
        "endCursor": "eyJpZHgiOjR9"
      }
    }
  }
}

Common Query Patterns

Fetching More Fields

Request additional fields by adding them to the node selection:

query {
  productViewConnection(first: 5) {
    edges {
      node {
        productId
        description
        skuList
        unitsInStock
        itemPrice
      }
    }
  }
}

Filtering Results

Apply filters to narrow down results:

query {
  orderViewConnection(
    first: 10
    type: ["SALES_ORDER"]
    status: ["OPEN", "IN_PROGRESS"]
  ) {
    edges {
      node {
        orderId
        orderDate
        status
      }
    }
  }
}

Sorting Results

Order results by one or more fields:

query {
  orderViewConnection(
    first: 10
    sort: [{ field: "orderDate", mode: "desc" }]
  ) {
    edges {
      node {
        orderId
        orderDate
      }
    }
  }
}

Paginating Through Results

Use cursors to fetch subsequent pages:

# First page
query {
  productViewConnection(first: 50) {
    edges {
      node {
        productId
        description
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

# Next page (use endCursor from previous response)
query {
  productViewConnection(
    first: 50
    after: "eyJpZHgiOjUwfQ=="
  ) {
    edges {
      node {
        productId
        description
      }
    }
    pageInfo {
      hasNextPage
      endCursor
    }
  }
}

Querying Related Data

Fetch related data in a single request:

query {
  orderViewConnection(first: 10) {
    edges {
      node {
        orderId
        orderDate
        customer {
          name
          email
        }
        origin {
          locationId
          name
        }
      }
    }
  }
}

Using Variables

Make queries reusable with variables:

query GetOrders($pageSize: Int!, $orderType: [String!]) {
  orderViewConnection(
    first: $pageSize
    type: $orderType
  ) {
    edges {
      node {
        orderId
        type
      }
    }
  }
}

Request body with variables:

{
  "operationName": "GetOrders",
  "variables": {
    "pageSize": 20,
    "orderType": ["SALES_ORDER", "RETURN_ORDER"]
  },
  "query": "query GetOrders($pageSize: Int!, $orderType: [String!]) { ... }"
}

Available Collections

Common collections you can query:

  • productViewConnection - Products and inventory
  • orderViewConnection - Sales orders, purchase orders, transfers
  • locationViewConnection - Warehouse and store locations
  • partyViewConnection - Customers and suppliers
  • stockItemViewConnection - Stock item details
  • inventoryTransactionViewConnection - Inventory movements

See the API Reference for a complete list.

Next Steps

Learn Core Concepts

Explore Reference Documentation

Build Your Integration

  1. Design your data model based on available collections
  2. Write queries to fetch the data you need
  3. Implement pagination for large datasets
  4. Add error handling and retry logic
  5. Test with your Finale account data

Tips for Success

  1. Start small: Begin with simple queries and gradually add complexity
  2. Use GraphQL introspection: Query the schema to discover available fields
  3. Test in isolation: Use tools like GraphiQL or Postman to test queries
  4. Monitor performance: Watch query execution times and optimize as needed
  5. Handle errors gracefully: Always check for errors in responses
  6. Respect rate limits: Implement backoff strategies for production use

Example: Complete Integration Script

// Fetch all open sales orders with customer information
async function getOpenOrders() {
  let hasNextPage = true
  let cursor = null
  const allOrders = []

  // Create base64 encoded credentials from API key and secret
  const credentials = Buffer.from(`${process.env.FINALE_KEY}:${process.env.FINALE_SECRET}`).toString('base64')

  while (hasNextPage) {
    const response = await fetch('https://app.finaleinventory.com/youraccount/api/graphql', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'Authorization': `Basic ${credentials}`,
      },
      body: JSON.stringify({
        operationName: 'GetOrders',
        variables: {
          first: 100,
          after: cursor,
        },
        query: `
          query GetOrders($first: Int!, $after: String) {
            orderViewConnection(
              first: $first
              after: $after
              type: ["SALES_ORDER"]
              status: ["OPEN"]
              sort: [{ field: "orderDate", mode: "desc" }]
            ) {
              edges {
                node {
                  orderId
                  orderDate
                  status
                  customer {
                    name
                    email
                  }
                }
              }
              pageInfo {
                hasNextPage
                endCursor
              }
            }
          }
        `,
      }),
    })

    const data = await response.json()

    if (data.errors) {
      console.error('GraphQL errors:', data.errors)
      break
    }

    const connection = data.data.orderViewConnection
    allOrders.push(...connection.edges.map(e => e.node))
    hasNextPage = connection.pageInfo.hasNextPage
    cursor = connection.pageInfo.endCursor
  }

  return allOrders
}

// Usage
getOpenOrders()
  .then(orders => {
    console.log(`Fetched ${orders.length} open orders`)
    console.log(orders)
  })
  .catch(error => {
    console.error('Failed to fetch orders:', error)
  })