---
title: Updating Resources with RAVE Connections
slug: updating-resources-with-rave-connections
description: Sync your Paccurate Resource Library with RAVE Connections—pull data from WMS/ERP/REST APIs, map JSON fields to items/cartons/orders, schedule imports, and use the RAVE REST API to create, update, or overwrite resources with unit conversion support.
icon: ⚡
docTags: 
createdAt: 2026-07-15T17:29:58.655Z
---

RAVE Connections let you keep your Paccurate Resource Library in sync with external data sources — whether that's a dimensioning system like Qboid, a WMS, an ERP, or any REST API that can return JSON. Once a connection is configured, you can pull data in on a schedule, trigger an import manually, or push data directly via the RAVE REST API.



:::hint{type="warning"}
RAVE Connections are available to Premium & Enterprise plans only. Please reach out to your customer success manager to enable them on your account
:::



This guide walks through setting up a connection, understanding how data is mapped, and using the API to read and write resource data.

## What is a RAVE Connection?

A RAVE Connection is a bridge between an external data source and a Paccurate Resource Library list (Items, Cartons, or Orders). Each connection defines:

- **Where** to pull data from (a third-party API endpoint)
- **How** to authenticate with that source
- **How** to translate the incoming data fields into Paccurate resource fields (Schema Map)
- **When** to run automatically (scheduling)
- **Which resource** to create or update

Each connection also generates its own API credentials, enabling direct programmatic writes to the resource without going through the third-party source at all.

**RAVE** is an acronym for “Really Awesome Value Extractor” — Paccurate decided to keep the working name because our customers *are* awesome, and so is their data.

\--

## Step 1 — Create a Connection

Navigate to your plan's RAVE Connections page:

`https://manage.paccurate.io/plans/<plan_id>/rave-connections`

Click **New Rave Connection** to open the connection editor.

### General Settings

| Field                      | Description                                                                                                     |
| -------------------------- | --------------------------------------------------------------------------------------------------------------- |
| **Name**                   | A short, descriptive label for this connection                                                                  |
| **Account**                | Which Paccurate account to use for resource access                                                              |
| **Resource Type**          | The type of resource to populate: items, cartons, or orders                                                     |
| **New Resource Base Name** | Prefix used when creating a new resource (e.g. qboid\_items)                                                    |
| **Resource to Update**     | Leave blank to always create a new resource, or select an existing resource to overwrite/update it on each sync |

### Connection Details

This section tells Paccurate where to pull data from and how to authenticate with the external source.

| Field                     | Description                                                                                                      |
| ------------------------- | ---------------------------------------------------------------------------------------------------------------- |
| **Third-Party API URL**   | The fully qualified endpoint URL that returns the source data                                                    |
| **Third-Party API Key**   | Stored credential, accessible as \{\{ api\_key }} in the headers template                                        |
| **Third-Party API Token** | Stored credential, accessible as \{\{ api\_token }} in the headers template                                      |
| **API Headers Template**  | Valid JSON sent as headers on each webhook request. Use \{\{ api\_key }} and \{\{ api\_token }} as placeholders. |

**Example headers template:**

:::BlockQuote
\{
&#x20; "Authorization": "Bearer \{\{ api\_token }}",
&#x20; "X-Api-Key": "\{\{ api\_key }}"
}
:::

***

## Step 2 — Map Your Data

This is where you tell Paccurate how to translate fields from your external source into resource properties.

### Schema Root Path

The name of the top-level property in the API response that contains the array of records to import. For example, if the API returns:

:::BlockQuote
\{ "scans": \[ \{ "id": 1, "l": 10, "w": 8, "h": 6 } ] }
:::

…then your Schema Root Path is scans.

### Schema Map

A JSON object where each key is a Paccurate resource property and each value is the corresponding field name in your source data. Dot notation is supported for nested fields.

**Format:**

:::BlockQuote
\{
&#x20; "\<paccurate\_property>": "\<source\_field>"
}
:::

**Example (Qboid → Paccurate Items):**

```json
{
  "refId": "id",
  "weight": "weight",
  "sequence": "barcode",
  "dimensions_x": "h",
  "dimensions_y": "w",
  "dimensions_z": "l",
  "properties.batt": "attributes.batt",
  "properties.fold": "attributes.fold item",
  "properties.frgl": "attributes.frgl",
  "properties.hazmat": "attributes.hazmat"
}
```

### Available Paccurate Item Properties

| Property      | Required | Type              |
| ------------- | -------- | ----------------- |
| refId         | ✅ Yes    | integer or string |
| dimensions\_x | ✅ Yes    | float             |
| dimensions\_y | ✅ Yes    | float             |
| dimensions\_z | ✅ Yes    | float             |
| weight        | No       | float             |
| name          | No       | string            |
| color         | No       | string            |
| sequence      | No       | string            |
| properties    | No       | JSON object       |

## Step 3 — Set a Schedule (Optional)

If you want Paccurate to automatically pull from the external source on a recurring basis, configure scheduling:

| Field                 | Description                                                                           |
| --------------------- | ------------------------------------------------------------------------------------- |
| **Start Date & Time** | The first time the sync should run; all future runs are calculated from this baseline |
| **Sync Frequency**    | Hourly, Daily, Weekly, or Monthly                                                     |

If you don't need automatic scheduling, you can skip this and trigger syncs manually or via the API.

***

## Step 4 — Save and Get Your API Secret

Click **Create**. After saving, Paccurate will generate an API Secret for this connection.

:::BlockQuote
⚠️ **Copy your secret immediately.** It will not be shown again. The first 10 characters (the *secret stem*) are saved and displayed in the editor so you can confirm which secret is active.
:::

You can regenerate credentials at any time from the connection editor. Regenerating immediately invalidates the previous values.

***

## &#x20;Triggering an Import Manually

To run a one-time pull from the third-party source:

1. Open the connection in PacManage
2. Go to **Connection Details**
3. Click **Trigger Webhook**

After the import runs, check the connection log to confirm success and see how many records were processed. Newly imported resources appear in the Resource Library under the applicable type (Items, Cartons, Orders), prefixed with the **New Resource Base Name** you set.

***

## Unit Conversions

The RAVE REST API supports automatic unit conversion during data ingestion. Pass conversion parameters as URL parameters or request headers on any POST, PUT, or PATCH request. Conversions are applied *after* the schema map is evaluated, so values are stored already in the converted unit.

| Parameter    | Header                  | Values                 | Converts          |
| ------------ | ----------------------- | ---------------------- | ----------------- |
| dim\_conv    | X-Paccurate-Dim-Conv    | mm\_to\_in, in\_to\_mm | dimensions\_x/y/z |
| weight\_conv | X-Paccurate-Weight-Conv | gr\_to\_lb, lb\_to\_gr | weight            |

**Example URL:**

`https://manage.paccurate.io/rave-api/your_public_api_id/rest?dim_conv=mm_to_in&weight_conv=gr_to_lb`

***

## Using the RAVE REST API

In addition to scheduled and manual webhook imports, each RAVE Connection exposes a REST API that lets you push data directly into a resource — no third-party source required. This is useful for integrations where your system wants to send data to Paccurate in real time.

### Authentication

Pass your API Secret on every request using one of two methods:

**URL parameter:**

`?pac_api_secret=your_secret_here`

**Request header:**

`X-Paccurate-API-Secret: your_secret_here`

### Base URLs

| Purpose                      | URL                                                            |
| ---------------------------- | -------------------------------------------------------------- |
| Trigger webhook import       | `https://manage.paccurate.io/rave-api/{public_api_id}/webhook` |
| Direct resource manipulation | `https://manage.paccurate.io/rave-api/{public_api_id}/rest`    |

## API Reference

### GET — Trigger Webhook Import

Triggers a pull from the third-party API URL configured in Connection Details and imports the result into the connected resource. Behaves identically to clicking **Trigger Webhook** in PacManage.

- If **Resource to Update** is blank → creates a new resource
- If **Resource to Update** is set → overwrites that resource with the imported data

**Endpoint:** <font color="#15803D">**GET**</font> `/rave-api/{public_api_id}/webhook`

### POST — Create or Upsert

Send data directly to create a new resource or upsert rows into an existing one.

- **No Resource to Update set** → creates a new resource from the payload
- **Resource to Update set** → upserts into the existing resource (same behavior as PATCH)

**Endpoint:** <font color="#CA8A04">**POST**</font> `/rave-api/{public_api_id}/rest`

**Response:**

:::BlockQuote
\{ "packResourceId": 12345, "status": "success" }
:::

**Create a new resource with a single item:**

```json
{
  "payload": {
    "id": 325144,
    "l": 111,
    "w": 106,
    "h": 10,
    "weight": 55793,
    "barcode": "",
    "attributes": { "stackable": "yes" }
  }
}
```

**Create a new resource with multiple items:**

```json
{
  "payload": [
    {
      "id": 325144,
      "l": 111,
      "w": 106,
      "h": 10,
      "weight": 55793,
      "attributes": { "stackable": "yes" }
    },
    {
      "id": 325053,
      "l": 240,
      "w": 170,
      "h": 87,
      "barcode": "0901B001",
      "attributes": { "foldable": true }
    }
  ]
}
```

**Upsert into an existing resource (with row matching):**

Use row\_key to specify which field(s) should be used to match incoming rows against existing rows. Use mapped property names (e.g. refId, not id). Matched rows are updated; unmatched rows are inserted.

```json
{
  "payload": [
    {
      "id": 325144,
      "weight": 50,
      "attributes": { "foldable": true }
    },
    {
      "id": 325053,
      "weight": 100,
      "attributes": { "foldable": true }
    },
    {
      "id": 325131,
      "l": 141,
      "w": 49,
      "h": 32,
      "barcode": "",
      "attributes": { "other": "orientation lock" }
    }
  ],
  "row_key": ["refId"]
}
```

:::BlockQuote
In this example, the first two records exist in the resource and will be updated. The third is new and will be inserted — which is why it requires a full/complete object.
:::

### PUT — Overwrite

Replaces the entire contents of an existing resource with the payload data. **Resource to Update must be set.**

- Payload must be an array of complete objects (no partial records)
- All existing rows are removed before the new data is written

**Endpoint:** <font color="#4338CA">**PUT**</font> `/rave-api/{public_api_id}/rest`

**Response:**

:::BlockQuote
\{ "status": "success" }
:::

**Overwrite a resource with three items:**

```json
{
  "payload": [
    {
      "id": 325144,
      "l": 111,
      "w": 106,
      "h": 10,
      "weight": 55793,
      "barcode": "",
      "attributes": { "stack item": "ruleneeded" }
    },
    {
      "id": 325053,
      "l": 240,
      "w": 170,
      "h": 87,
      "barcode": "0901B001",
      "attributes": { "stack item": "internalspace" }
    },
    {
      "id": 325131,
      "l": 141,
      "w": 49,
      "h": 32,
      "barcode": "",
      "attributes": { "other": "orientation lock" }
    }
  ]
}
```

### PATCH — Upsert / Append

Adds or merges rows into an existing resource without clearing it first. **Resource to Update must be set.**

- **With row\_key:** incoming rows are matched against existing rows. Matches are merged; non-matches are inserted as new rows.
- **Without row\_key:** all incoming rows are appended to the end of the resource without any deduplication.

row\_key can be passed three ways:

| Method        | Example                              |
| ------------- | ------------------------------------ |
| Body property | "row\_key": \["refId"]               |
| URL parameter | ?row\_key=\["refId"]                 |
| Header        | X-Paccurate-Rave-Row-Key: \["refId"] |

**Endpoint:** <font color="#4338CA">**PATCH**</font> `/rave-api/{public_api_id}/rest`

**Response:**

:::BlockQuote
\{ "status": "success" }
:::

**Upsert with row matching:**

```json
{
  "payload": [
    {
      "id": 325144,
      "weight": 50,
      "attributes": { "foldable": true }
    },
    {
      "id": 325053,
      "weight": 100,
      "attributes": { "foldable": true }
    },
    {
      "id": 325131,
      "l": 141,
      "w": 49,
      "h": 32,
      "barcode": "",
      "attributes": { "other": "orientation lock" }
    }
  ],
  "row_key": ["refId"]
}
```

**Append without matching (no row\_key):**

```json
{
  "payload": [
    {
      "id": 325999,
      "l": 50,
      "w": 40,
      "h": 20,
      "weight": 1000,
      "barcode": "NEW-ITEM-001",
      "attributes": {}
    }
  ]
}
```

***

## Response Codes & Errors

Applies to all POST, PUT, and PATCH requests to /rave-api/\{public\_api\_id}/rest.

| HTTP Status      | Response Body                                                         | When It Happens                                                                                                                                                                                     |
| ---------------- | --------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| 200 OK           | `{ "status": "success" } `(POST also includes "packResourceId")       | The write completed successfully.                                                                                                                                                                   |
| 200 OK           | `{ "status": "failure" }` (POST also includes "packResourceId": null) | The request was authenticated but the write didn't complete — e.g. **Resource to Update** isn't set for PUT/PATCH, or the upsert/overwrite failed internally. Check the connection log for details. |
| 400 Bad Request  | `{ "error": "Invalid JSON payload" }`                                 | payload could not be parsed as JSON.                                                                                                                                                                |
| 400 Bad Request  | `{ "error": "Invalid row_key format" }`                               | row\_key (body, URL parameter, or header) was not a string or a JSON array.                                                                                                                         |
| 401 Unauthorized | `{ "error": "Unauthorized" }`                                         | The API Secret is missing, incorrect, or doesn't match the public\_api\_id in the URL.                                                                                                              |

:::BlockQuote
⚠️ A 200 response does not guarantee the write succeeded — always check the status field in the response body, not just the HTTP status code.
:::

***

## Quick Reference: Which Action Should I Use?

| **Goal**                                         | **Method**                                                                             |
| ------------------------------------------------ | -------------------------------------------------------------------------------------- |
| Pull from external API (scheduled or manual)     | <font color="#15803D">**GET**</font> `/webhook`                                        |
| Create a brand new resource from scratch         | <font color="#CA8A04">**POST**</font> `/rest` (no Resource to Update set)              |
| Replace everything in a resource                 | <font color="#4338CA">**PUT**</font> `/rest`                                           |
| Add new rows without touching existing rows      | <font color="#6B21A8">**PATCH**</font> `/rest` (no row\_key)                           |
| Update specific rows by matching key, insert new | <font color="#6B21A8">**PATCH**</font> `/rest` with row\_key                           |
| Update specific rows or insert, via POST         | <font color="#CA8A04">**POST**</font> `/rest` with row\_key and Resource to Update set |

