Connecting an existing carrier account ("Bring Your Own Carrier" / BYOC)

Have your own carrier account(s) to connect? You're in the right place.

Introduction

This article describes how to connect a 3PL-owned or brand-owned existing account with a shipping carrier (e.g., UPS, FedEx, USPS) within the iDrive platform. This is commonly referred to as "Bring Your Own Carrier" (BYOC). Connecting an existing carrier account allows you to use your negotiated rates and contracts through iDrive's technology infrastructure.

Carrier accounts are built on two key concepts:

  • Connection — Represents the actual carrier credentials and contract. A connection is created once and holds the real-world account details (account numbers, credentials, contract information).
  • Carrier Account — Represents a tenant's authorization to use a connection. Multiple carrier accounts can point to the same connection, enabling shared access across tenants while maintaining strict tenant isolation.

Key Concept: The connection is the single source of truth for your carrier credentials. Carrier accounts are lightweight records that grant specific tenants access to that connection. This separation ensures tenant isolation while supporting flexible sharing scenarios.

Base URLs

Use the correct base URL for your environment:

Sandbox: https://api.beta.idrivelogistics.com

Production: https://api.idrivelogistics.com

Append the specific API route to the base URL (e.g., /api/v1/carrierAccounts).

Environment Warning: Carrier account IDs and connection IDs are unique to each environment. IDs from sandbox will not work in production and vice versa. Always verify you're using the correct IDs for your target environment.

API Endpoints Overview

The Carrier Accounts API provides the following endpoints:

MethodEndpointDescription
POST/api/v1/carrierAccountsCreate a carrier account (and optionally a new connection)
GET/api/v1/carrierAccountsList carrier accounts for a tenant
GET/api/v1/carrierAccounts/{id}Get a specific carrier account
PUT/api/v1/carrierAccounts/{id}Update a carrier account
DELETE/api/v1/carrierAccounts/{id}Delete a carrier account

Understanding the Two Scenarios

Before diving into the API calls, it's important to understand which scenario applies to your integration. The API calls are the same — the difference is how many times you call them and why.

Scenario A: Direct Integration (Single Tenant)

You have one tenant and want to connect your own carrier account. This is the simplest case: one API call creates both the connection and the carrier account.

Scenario B: 3PL with Brand Tenants

You are a 3PL (thirdPartyLogistic tenant) with multiple brand tenants representing your clients. You have a carrier account that you want your brand tenants to ship on. This requires creating the connection once, then granting access to each brand tenant that should use it.

Why does the 3PL scenario require multiple calls? iDrive enforces strict tenant isolation. A carrier account created under one tenant is not visible to other tenants — even child tenants. This is by design. The connection is the shared object; carrier accounts are per-tenant authorization records that grant access to that connection. This model ensures you can control exactly which brand tenants have access to your carrier credentials.

For more on how tenant hierarchies work, see the Tenants API documentation.

Scenario A: Direct Integration (Single Tenant)

For a direct integration with no child tenants, connecting a carrier account is a single API call.

Create the Carrier Account and Connection

POST /api/v1/carrierAccounts

Headers

Authorization: Bearer YOUR_ACCESS_TOKEN
x-tenant-id: YOUR_TENANT_ID
Content-Type: application/json

Example Request (UPS)

{
  "name": "My UPS Account",
  "carrierAccountConnection": {
    "name": "My UPS Connection",
    "ownershipType": "BRAND",
    "connectionDetails": {
      "carrier": "UPS",
      "accountNumber": "YOUR_ACCOUNT_NUMBER"
    }
  }
}

Request Fields

  • name — (Required) A friendly name for this carrier account (2–100 characters)
  • ownerTenantId — (Optional) The tenant ID that will own this carrier account. If omitted, the carrier account will belong to the tenant specified in the x-tenant-id header.
  • carrierAccountConnection — (Required when creating a new connection) Contains the connection details:
    • name — (Required) A name for the connection (2–100 characters)
    • ownershipType — (Required) Set to "BRAND" for direct integrations
    • connectionDetails — (Required) Carrier-specific credentials. Structure varies by carrier (see examples below).

Note: The connectionDetails structure differs per carrier. For example, UPS requires carrier and accountNumber, while FedEx requires carrier, accountNumber, contactInfo, and billingAddress. Refer to the API reference for carrier-specific schemas.

Example Response

{
  "id": "ca_abc123",
  "name": "My UPS Account",
  "tenantId": "your-tenant-id",
  "carrier": "UPS",
  "ownershipType": "BRAND",
  "carrierAccountConnectionId": "conn_xyz789",
  "carrierAccountConnection": {
    "id": "conn_xyz789",
    "name": "My UPS Connection",
    "authorizationStatus": "PENDING",
    "authorizationDetails": {
      "type": "OAUTH2",
      "status": "PENDING",
      "oauth_url": "https://www.ups.com/lasso/signin?..."
    }
  },
  "serviceLevels": ["UPS_GROUND", "UPS_NEXT_DAY_AIR", "..."],
  "isActive": true,
  "locationIds": [],
  "allowedLocationIds": [],
  "createdAt": "2025-01-15T10:30:00Z",
  "updatedAt": "2025-01-15T10:30:00Z"
}

Authorizing the Connection

Depending on the carrier, the connection may require an additional authorization step before it can be used for rating or label purchasing. The authorizationStatus field on the carrierAccountConnection indicates the current state.

Possible values for authorizationStatus:

  • UNAUTHORIZED — The connection has not been authorized
  • PENDING — Authorization has been initiated but not yet completed
  • AUTHORIZED — The connection is fully authorized and ready to use
  • EXPIRED — The authorization has expired and needs to be renewed
  • ERROR — An error occurred during authorization

For carriers that use OAuth (e.g., UPS): The response will include an authorizationDetails object with "type": "OAUTH2" and an oauth_url. The carrier account owner must visit this URL in a browser and complete the carrier's authorization flow to grant iDrive access to the account. Until this is done, the connection and all attached carrier accounts will be unavailable for rating or label purchasing.

For carriers that use API keys (e.g., FedEx, OnTrac): Authorization may happen automatically based on the credentials provided in connectionDetails. The authorizationDetails will show "type": "APIKEY" with the corresponding status.

You can check the current authorization status at any time by retrieving the carrier account:

GET /api/v1/carrierAccounts/{id}

The carrierAccountConnection.authorizationStatus field in the response will reflect the current state. Once the status is AUTHORIZED, the carrier account is ready for use.

Important: Do not attempt to request rates or purchase labels until the connection's authorizationStatus is AUTHORIZED. Requests made against an unauthorized connection will fail.

Scenario B: 3PL with Brand Tenants

This is the most common BYOC scenario. A 3PL has their own carrier account (e.g., a UPS contract) and wants their brand tenants to ship using that account. This is a two-phase process:

  1. Create the connection and verify it — This establishes the carrier credentials in iDrive under the 3PL's own tenant, allowing you to complete any authorization steps and verify the connection works before sharing it with brand tenants.
  2. Grant access to brand tenants — For each brand tenant that should use this carrier account, create an additional carrier account tied to the same connection.

Phase 1: Create the Connection

This call creates the connection (your carrier credentials) and a carrier account under the 3PL's own tenant. Because ownerTenantId is omitted, the carrier account will belong to the tenant making the call — the 3PL itself. This lets you verify the connection and complete any carrier authorization before involving brand tenants.

POST /api/v1/carrierAccounts

Headers

Authorization: Bearer YOUR_ACCESS_TOKEN
x-tenant-id: YOUR_3PL_TENANT_ID
Content-Type: application/json

Example Request

{
  "name": "3PL UPS Account",
  "carrierAccountConnection": {
    "name": "3PL UPS Connection",
    "ownershipType": "PARTNER",
    "connectionDetails": {
      "carrier": "UPS",
      "accountNumber": "YOUR_ACCOUNT_NUMBER"
    }
  }
}

Request Fields

  • name — (Required) A friendly name for this carrier account (2–100 characters)
  • ownerTenantId — (Optional) If omitted, the carrier account will belong to the tenant in the x-tenant-id header (the 3PL itself). This is the recommended approach for Phase 1 — it lets you verify the connection under your own tenant first.
  • carrierAccountConnection — (Required) Contains the connection details:
    • name — (Required) A name for the connection
    • ownershipType — (Required) Set to "PARTNER" for 3PL-managed carrier accounts
    • connectionDetails — (Required) Your carrier account credentials. These are only provided on this first call.

Example Response

{
  "id": "ca_3pl_001",
  "name": "3PL UPS Account",
  "tenantId": "your-3pl-tenant-id",
  "carrier": "UPS",
  "ownershipType": "PARTNER",
  "carrierAccountConnectionId": "conn_shared_789",
  "carrierAccountConnection": {
    "id": "conn_shared_789",
    "name": "3PL UPS Connection",
    "authorizationStatus": "PENDING",
    "authorizationDetails": {
      "type": "OAUTH2",
      "status": "PENDING",
      "oauth_url": "https://www.ups.com/lasso/signin?..."
    }
  },
  "serviceLevels": ["UPS_GROUND", "UPS_NEXT_DAY_AIR", "..."],
  "isActive": true,
  "locationIds": [],
  "allowedLocationIds": [],
  "createdAt": "2025-01-15T10:30:00Z",
  "updatedAt": "2025-01-15T10:30:00Z"
}

At this point, complete the authorization process if required (see Authorizing the Connection above). For UPS, the account owner will need to visit the oauth_url and grant access. Once authorizationStatus shows AUTHORIZED, you can verify the connection by requesting rates under the 3PL's own tenant before sharing with brand tenants.

Tip: The carrierAccountConnectionId (conn_shared_789 in this example) is what you'll use in Phase 2 to share this connection with brand tenants. You can always retrieve this value later by calling GET /api/v1/carrierAccounts — it is included in the response for every carrier account that is linked to a connection.

Phase 2: Grant Access to Brand Tenants

Once the connection is authorized and verified, create a carrier account for each brand tenant that should have access. This creates a new carrier account tied to the existing connection.

POST /api/v1/carrierAccounts

Headers

Authorization: Bearer YOUR_ACCESS_TOKEN
x-tenant-id: YOUR_3PL_TENANT_ID
Content-Type: application/json

Example Request

{
  "name": "3PL UPS Account - Brand Alpha",
  "ownerTenantId": "brand-alpha-tenant-id",
  "carrierAccountConnectionId": "conn_shared_789"
}

Request Fields

  • name — (Required) A friendly name for this brand's carrier account
  • ownerTenantId — (Required for this phase) The tenant ID of the brand being granted access. Unlike Phase 1, you must specify this — otherwise the carrier account would be created under the 3PL's tenant again.
  • carrierAccountConnectionId — (Required) The connection ID from Phase 1. This is what links this carrier account to your existing carrier credentials.

Notice: No carrierAccountConnection object or connectionDetails are needed. The credentials already exist on the connection. You are simply granting a new tenant access to them.

Example Response

{
  "id": "ca_brand_alpha_001",
  "name": "3PL UPS Account - Brand Alpha",
  "tenantId": "brand-alpha-tenant-id",
  "carrier": "UPS",
  "ownershipType": "PARTNER",
  "carrierAccountConnectionId": "conn_shared_789",
  "carrierAccountConnection": {
    "id": "conn_shared_789",
    "name": "3PL UPS Connection",
    "authorizationStatus": "AUTHORIZED"
  },
  "serviceLevels": ["UPS_GROUND", "UPS_NEXT_DAY_AIR", "..."],
  "isActive": true,
  "locationIds": [],
  "allowedLocationIds": [],
  "createdAt": "2025-01-15T10:35:00Z",
  "updatedAt": "2025-01-15T10:35:00Z"
}

Repeat Phase 2 for each brand tenant that needs access.

How It All Fits Together

Here is a summary of what the 3PL setup looks like after connecting one carrier account and sharing it with three brand tenants:

3PL Tenant (thirdPartyLogistic)
│
│   Connection: conn_shared_789
│   └── Carrier credentials (UPS account, stored once)
│
├── 3PL itself
│   └── Carrier Account: ca_3pl_001 (created in Phase 1)
│
├── Brand Alpha (brand tenant)
│   └── Carrier Account: ca_brand_alpha_001
│
├── Brand Bravo (brand tenant)
│   └── Carrier Account: ca_brand_bravo_002
│
└── Brand Charlie (brand tenant)
    └── Carrier Account: ca_brand_charlie_003

When you request rates or purchase a label for Brand Bravo using brand-bravo-tenant-id, iDrive resolves the carrier accounts available to that tenant — including the one linked to your shared connection. The carrier credentials are never duplicated. Each brand tenant simply has its own authorization record.

Key Concept: You do not need to pass carrier account IDs when requesting rates. iDrive resolves available carrier accounts based on the tenant ID. As long as the brand tenant has a carrier account linked to the connection, the BYOC rates will be included automatically.

Removing Access for a Brand Tenant

To revoke a specific brand's access to the shared carrier account, delete their carrier account record. This does not affect the connection or any other brand tenant's access.

DELETE /api/v1/carrierAccounts/{carrierAccountId}

DELETE /api/v1/carrierAccounts/ca_brand_bravo_002
Authorization: Bearer YOUR_ACCESS_TOKEN
x-tenant-id: YOUR_3PL_TENANT_ID

After deletion, Brand Bravo will no longer see BYOC rates from this connection. Brand Alpha and Brand Charlie are unaffected.

Rating and Label Purchasing

Once carrier accounts are set up, requesting rates and purchasing labels works the same regardless of whether the account is direct or shared via a 3PL.

When making rate requests (POST /api/v1/rates), use the brand tenant's ID in the x-tenant-id header. iDrive will automatically resolve all carrier accounts available to that tenant, including BYOC accounts connected through the sharing mechanism described above. The options.carrierAccountIds field on the rate request is optional — if omitted, all of the tenant's carrier accounts will be used.

When purchasing a label (POST /api/v1/labels), you will need to provide the carrierAccountId for the selected rate. This value is returned in the rate response under shipmentRates[].carrierAccount.id.

Best Practices

  • Verify before sharing — In the 3PL scenario, create the connection under your own tenant first (Phase 1), complete authorization, and confirm rates are returned before granting access to brand tenants.
  • Use descriptive names — Include the brand name in carrier account names (e.g., "3PL UPS Account - Brand Alpha") to make troubleshooting easier
  • Use PARTNER ownership for 3PL scenarios — This correctly signals that the 3PL owns the carrier relationship and is granting access to brand tenants
  • Use BRAND ownership for direct integrations — This signals the tenant owns and manages their own carrier account
  • Don't duplicate credentials — Never create separate connections for the same carrier account. Use the carrierAccountConnectionId to share a single connection across brand tenants.
  • Verify environment-specific IDs — Connection IDs and carrier account IDs are environment-specific. Always double-check you're using the correct IDs for sandbox vs. production.
  • Monitor authorization status — After creating a connection, check authorizationStatus before attempting to use it. For OAuth-based carriers like UPS, the account owner must complete the authorization flow before rates or labels will work.

Troubleshooting Common Issues

Issue: No BYOC rates returned for a brand tenant

Solution: Verify that a carrier account exists for that brand tenant's ID and is linked to the correct connection. Use GET /api/v1/carrierAccounts with the brand's tenant ID to confirm. Also check that the connection's authorizationStatus is AUTHORIZED — an unauthorized or expired connection will not return rates.

Issue: Phase 2 call fails or does not link to the existing connection

Solution: Ensure you are passing the carrierAccountConnectionId from the Phase 1 response in the request body. Without the carrierAccountConnectionId, iDrive will expect a carrierAccountConnection object with full credentials — which is only intended for Phase 1.

Issue: "Unauthorized" or "tenant not found" errors

Solution: Verify that the x-tenant-id header is set to the 3PL tenant ID (thirdPartyLogistic) and that the ownerTenantId in the body is a valid brand tenant under that 3PL.

Issue: Brand tenant sees rates from a carrier account they should not have access to

Solution: Check for an unintended carrier account linked to that brand tenant. Use GET /api/v1/carrierAccounts with the brand's tenant ID to audit their carrier account records.

Issue: Connection shows authorizationStatus of PENDING or UNAUTHORIZED

Solution: The carrier authorization has not been completed. For OAuth-based carriers (e.g., UPS), retrieve the carrier account via GET /api/v1/carrierAccounts/{id} and check the carrierAccountConnection.authorizationDetails.oauth_url. The account owner must visit this URL and complete the carrier's authorization flow. For API key-based carriers, verify that the credentials provided in connectionDetails are correct.

Issue: Rates stopped working for all brand tenants on a connection

Solution: The connection's authorization may have expired. Retrieve any carrier account linked to the connection and check the carrierAccountConnection.authorizationStatus. If it shows EXPIRED, the account owner will need to re-authorize the connection.

Need Help?

  • API Reference: https://idrivelogistics.readme.io/reference
  • Tenants Guide: Review the Tenants API documentation for tenant hierarchy and setup
  • Shipping Sites Guide: Review the Shipping Sites documentation for warehouse location setup
  • Support: Contact your iDrive account representative