Skip to main content
RapidDev - Software Development Agency
bubble-integrationsBubble API Connector

UPS API

Connect Bubble to the UPS REST API using OAuth 2.0 client credentials — but the Client Secret must never appear in a client-side workflow. The clean Bubble solution uses a Backend Workflow (paid plan) that mints a Bearer token server-side, caches it to avoid per-request round-trips, and makes the downstream UPS tracking or rating call. Sandbox and production use different base URLs AND different credentials — a common source of 401 errors at launch.

What you'll learn

  • How to register a UPS developer app and obtain Client ID and Client Secret
  • How to store UPS credentials securely as Bubble App Constants
  • How to build a Backend Workflow that mints a UPS OAuth Bearer token server-side
  • How to cache the access token to avoid per-request latency overhead
  • How to call UPS tracking and rating endpoints from within a Backend Workflow
  • Why UPS sandbox and production use different base URLs and different credentials
Book a free consultation
4.9Clutch rating
600+Happy partners
17+Countries served
190+Team members
Intermediate18 min read3–4 hoursProductivityLast updated July 2026RapidDev Engineering Team
TL;DR

Connect Bubble to the UPS REST API using OAuth 2.0 client credentials — but the Client Secret must never appear in a client-side workflow. The clean Bubble solution uses a Backend Workflow (paid plan) that mints a Bearer token server-side, caches it to avoid per-request round-trips, and makes the downstream UPS tracking or rating call. Sandbox and production use different base URLs AND different credentials — a common source of 401 errors at launch.

Quick facts about this guide
FactValue
ToolUPS API
CategoryProductivity
MethodBubble API Connector
DifficultyIntermediate
Time required3–4 hours
Last updatedJuly 2026

Why UPS Requires a Different Approach Than Other Shipping APIs

UPS's modern REST API (replacing the older XML API) uses OAuth 2.0 client credentials — a two-step flow where you first POST to a token endpoint with your Client ID and Secret, receive a time-limited Bearer token, and then use that token on downstream calls. This is more complex than a static API key but gives your Bubble app direct access to UPS tracking data, carrier rates, and address validation without a third-party shipping platform sitting in the middle.

The critical security constraint in Bubble: the Client Secret must never appear in a client-side workflow or API call. The solution is to handle the entire OAuth flow inside a Bubble Backend Workflow that runs server-side. The Backend Workflow stores the Client Secret in a Bubble App Constant marked Private, mints the token, caches it (to avoid 300-500ms round-trip latency on every request), and makes the downstream UPS call. The frontend triggers the Backend Workflow and receives the shipping data back.

UPS maintains separate sandbox (`wwwcie.ups.com`) and production (`onlinetools.ups.com`) environments with entirely separate credentials. Sandbox tracking numbers only work against the sandbox URL. This separation is a common source of silent failures at launch — verify both the base URL and credential set when switching environments.

Integration method

Bubble API Connector

Bubble's API Connector combined with a Backend Workflow handles UPS's two-step OAuth flow: a Backend Workflow mints and caches the Bearer token server-side, then calls the UPS endpoint. The Client Secret never reaches the browser.

Prerequisites

  • A UPS developer account at developer.ups.com — free to create, linked to a UPS My Choice or UPS account
  • A registered UPS developer app with a Client ID and Client Secret (created in the developer portal after account registration)
  • A paid Bubble plan — Backend Workflows are required to keep the Client Secret server-side and are not available on the Free plan
  • Bubble's API Connector plugin installed (Plugins tab → Add plugins → search 'API Connector' → Install)
  • Basic familiarity with Bubble's Backend Workflows tab and App Constants (both are under the Settings and left-sidebar panels)

Step-by-step guide

1

Register a UPS Developer App and Get Credentials

Go to developer.ups.com and sign in with your UPS account credentials (or create a new UPS developer account — it is free). Once logged in, click 'My Apps' in the navigation and then 'Create App'. When creating the app, you will be asked to select API products. For a package tracking integration, select 'Track API'. For shipping rate quotes, select 'Rating API'. For address validation, select 'Address Validation API'. You can add multiple products to a single app. Give the app a name like 'Bubble Integration'. After creating the app, you will see your **Client ID** and **Client Secret** in the app detail page. Copy both immediately — the Client Secret may not be shown again in full. Store them in a password manager. IMPORTANT: UPS issues separate credentials for sandbox and production. The app dashboard shows both. Use the sandbox credentials while building — they connect to `wwwcie.ups.com`. Use the production credentials for your live app — they connect to `onlinetools.ups.com`. Do not mix them. Also note which API products you have added. The UPS REST API is modular — you need to explicitly add each product (Tracking, Rating, Address Validation) to your app before you can call it.

ups-endpoints.txt
1# UPS API base URLs
2Sandbox: https://wwwcie.ups.com
3Production: https://onlinetools.ups.com
4
5# Token endpoint (same path, different base URL)
6Sandbox: https://wwwcie.ups.com/security/v1/oauth/token
7Production: https://onlinetools.ups.com/security/v1/oauth/token
8
9# Key API endpoints
10Tracking: /track/v1/details/{inquiryNumber}
11Rating: /rating/v2409/Rate
12Address: /addressvalidation/v1/1

Pro tip: If you see a 'product not enabled' error when calling a UPS endpoint, go back to the developer portal → My Apps → your app → Add Products, and add the specific API product you need (Tracking, Rating, etc.).

Expected result: You have a UPS developer app with sandbox Client ID and Client Secret. You have noted which API products are enabled. You understand the sandbox vs production URL separation.

2

Store Credentials as Bubble App Constants and Create a Token Cache Data Type

In your Bubble app, go to Settings → App Constants (this may be under Settings → General → App constants in your Bubble version). Add the following constants: - `ups_client_id` — your UPS Client ID (value: visible to all, no Private needed since Client ID is less sensitive) - `ups_client_secret` — your UPS Client Secret (mark this Private) - `ups_base_url` — `https://wwwcie.ups.com` for sandbox; change to `https://onlinetools.ups.com` for production Next, create a Bubble Data Type called 'UPSToken' with these fields: - `access_token` (text) — the Bearer token string returned by the UPS OAuth endpoint - `expiry_time` (date) — the calculated expiry datetime (current time + token TTL in seconds) - `is_active` (yes/no) — a flag you can use to quickly find the current valid token You only ever need one active UPS token record at a time. When you mint a new token, set `is_active` to 'No' on any existing records first, then create a new record with the new token and `is_active` set to 'Yes'. This gives you a simple 'Do a search for UPSToken where is_active is Yes → first item' lookup pattern at the start of each Backend Workflow execution.

bubble-constants-setup.txt
1// Bubble App Constants to create:
2// ups_client_id → "your_client_id_here"
3// ups_client_secret → "your_client_secret_here" (Private)
4// ups_base_url → "https://wwwcie.ups.com" (sandbox)
5
6// UPSToken Data Type fields:
7// access_token (text)
8// expiry_time (date)
9// is_active (yes/no)

Pro tip: Mark `ups_client_secret` as Private in App Constants. Private constants are not visible in Bubble's debugger or accessible through client-side workflows — they are only usable in Backend Workflows running server-side.

Expected result: App Constants for Client ID, Client Secret, and base URL are saved in Bubble Settings. A UPSToken Data Type exists with the three fields for caching the access token.

3

Build a Backend Workflow That Mints and Caches the UPS Access Token

Go to the Backend Workflows tab in Bubble (visible only on paid plans). Click 'New API Workflow'. Name it 'UPS Get Token'. This workflow will be called internally by other Backend Workflows — it does not need to be exposed as a public API endpoint. Inside the workflow, add these steps: **Step 1 — Check for a valid cached token:** Add a 'Do when condition is true' check: 'Search for UPSToken where is_active is Yes and expiry_time > Current date/time → count > 0'. If a valid token exists, the main tracking/rating workflow can use it directly. Design the parent workflow to check this before calling the token workflow. **Step 2 — Call the UPS token endpoint:** Add an API Connector call. In the API Connector, create a new API group called 'UPS OAuth'. Add a single call: Method POST, URL = `[ups_base_url App Constant]/security/v1/oauth/token`. Set Content-Type to `application/x-www-form-urlencoded` (not JSON — the token endpoint uses form encoding, not a JSON body). In the request body, add: - `grant_type` = `client_credentials` - `client_id` = `[ups_client_id App Constant]` - `client_secret` = `[ups_client_secret App Constant — Private]` **Step 3 — Cache the token:** After the API call, add a workflow action: 'Make changes to all UPSToken' where is_active is Yes → set `is_active` to No. Then 'Create a new UPSToken' with: - `access_token` = the `access_token` field from the API response - `expiry_time` = Current date/time + [token TTL in seconds from the `expires_in` response field] - `is_active` = Yes The UPS token endpoint returns `expires_in` as a number of seconds. If this value varies, store it dynamically; otherwise use a conservative value like 3600 seconds (1 hour) as a cache duration.

ups-token-endpoint.json
1// POST /security/v1/oauth/token — request
2// Content-Type: application/x-www-form-urlencoded
3// Body (form-encoded):
4grant_type=client_credentials&client_id=YOUR_CLIENT_ID&client_secret=YOUR_CLIENT_SECRET
5
6// Success response (200)
7{
8 "token_type": "Bearer",
9 "issued_at": "1720483200000",
10 "client_id": "YOUR_CLIENT_ID",
11 "access_token": "eyJraWQiOiJ...",
12 "expires_in": "14399",
13 "status": "approved"
14}
15
16// Cache logic:
17// expiry_time = Current time + (expires_in seconds)
18// If current time < expiry_time → use cached token
19// If current time >= expiry_time → mint new token

Pro tip: The UPS token endpoint uses form-encoded body (application/x-www-form-urlencoded), NOT JSON. In Bubble's API Connector, set the Content-Type header to `application/x-www-form-urlencoded` on the token call and use key-value pairs in the body section, not a JSON object.

Expected result: The UPS OAuth Backend Workflow successfully calls the token endpoint, receives an access_token, and creates a UPSToken record in Bubble's database with the token and its expiry time. Subsequent calls that find a valid cached token skip the minting step.

4

Build a Backend Workflow for Package Tracking

Create a second Backend Workflow. Name it 'UPS Track Package'. Add an input parameter: `tracking_number` (text). This is the workflow the frontend will trigger. Inside the workflow: **Step 1 — Get a valid token:** Check if a valid UPSToken record exists (is_active = Yes, expiry_time > Current date/time). If yes, use the cached token. If no, trigger the 'UPS Get Token' Backend Workflow from Step 3 first, wait for it to complete, then fetch the new UPSToken. **Step 2 — Call the UPS Tracking endpoint:** In the API Connector, add a new call to the UPS OAuth API group (or create a separate 'UPS API' group for the downstream calls). Name it 'Track Shipment'. Method: GET. URL: `[ups_base_url]/track/v1/details/[tracking_number]`. Add a call-level header: `Authorization: Bearer [access_token from cached UPSToken]`. This header is dynamic — it references the UPSToken Data Type, not a static App Constant — so it does not need to be Private in the traditional sense, but it is never sent to the browser because it is inside a Backend Workflow. Add query parameters: - `locale` = `en_US` - `returnSignature` = `false` Initialize the call using a real UPS sandbox tracking number (UPS provides test tracking numbers in the developer portal documentation). Set 'Use as' to 'Data'. **Step 3 — Parse the response and return data:** The UPS tracking response has a nested structure: `trackResponse.shipment[0].package[0].activity[0]` holds the most recent status update with `status.description` and `location.address`. Use Bubble's 'Extract JSON body value' steps to surface the key fields. Store them in a Bubble Data Type called 'UPSTrackingResult' or return them to the frontend via a Custom State. RapidDev's team has built UPS tracking integrations with Bubble for e-commerce clients, including token refresh logic and multi-package dashboards. If your use case is complex, reach out at rapidevelopers.com/contact for a free scoping call.

ups-tracking-response.json
1// GET /track/v1/details/{trackingNumber} — query params
2// ?locale=en_US&returnSignature=false
3// Headers: Authorization: Bearer eyJraWQiOiJ...
4
5// Sample response (simplified)
6{
7 "trackResponse": {
8 "shipment": [
9 {
10 "inquiryNumber": "1Z12345E0205271688",
11 "package": [
12 {
13 "trackingNumber": "1Z12345E0205271688",
14 "currentStatus": {
15 "description": "In Transit",
16 "code": "I"
17 },
18 "deliveryDate": [
19 { "date": "20260714", "type": "DEL" }
20 ],
21 "activity": [
22 {
23 "date": "20260709",
24 "time": "143000",
25 "location": {
26 "address": {
27 "city": "Louisville",
28 "stateProvince": "KY",
29 "country": "US"
30 }
31 },
32 "status": {
33 "description": "Package transferred to destination facility",
34 "code": "I"
35 }
36 }
37 ]
38 }
39 ]
40 }
41 ]
42 }
43}

Pro tip: UPS sandbox tracking numbers for testing are listed in the UPS developer portal documentation under 'Track API → Testing'. Use these test numbers — real UPS tracking numbers typically only resolve against the production API.

Expected result: The UPS Track Package Backend Workflow retrieves or reuses a cached Bearer token, calls the UPS Tracking endpoint with the provided tracking number, and returns the current shipment status, location, and estimated delivery date.

5

Build a Rating Call for Shipping Cost Estimates

Add a second downstream call to the UPS API. Name it 'Get Rate'. Method: POST. URL: `[ups_base_url]/rating/v2409/Rate`. Add `Content-Type: application/json` and `transactionSrc: Bubble` headers at the call level, plus the dynamic `Authorization: Bearer [token]` header. The UPS Rating API accepts a detailed JSON body with shipper, destination, and package information. Create a Backend Workflow called 'UPS Get Rate' with parameters for the destination address and package dimensions. In the workflow, first check for a valid cached token (same pattern as the tracking workflow). Then call the Get Rate action with a dynamically constructed JSON body. The response contains a `RateResponse.RatedShipment` array with each service level (Ground, 2-Day Air, Next Day Air) and its `TotalCharges.MonetaryValue`. Surface this array to the frontend so the user can select a shipping method at checkout. For the initialize call in the API Connector, use the UPS developer portal's sample request JSON — the Rating API body is complex and all fields must be present for a valid test response. Bubble's initialize step needs a real successful response to detect the schema correctly.

ups-rating-request.json
1// POST /rating/v2409/Rate — simplified request body
2{
3 "RateRequest": {
4 "Shipment": {
5 "Shipper": {
6 "Address": {
7 "PostalCode": "78701",
8 "CountryCode": "US"
9 }
10 },
11 "ShipTo": {
12 "Address": {
13 "City": "<dynamic: to_city>",
14 "StateProvinceCode": "<dynamic: to_state>",
15 "PostalCode": "<dynamic: to_postal>",
16 "CountryCode": "US"
17 }
18 },
19 "ShipFrom": {
20 "Address": {
21 "PostalCode": "78701",
22 "CountryCode": "US"
23 }
24 },
25 "Package": {
26 "PackagingType": { "Code": "02" },
27 "PackageWeight": {
28 "UnitOfMeasurement": { "Code": "LBS" },
29 "Weight": "<dynamic: weight_lbs>"
30 }
31 }
32 }
33 }
34}
35
36// Response — RatedShipment array
37{
38 "RateResponse": {
39 "RatedShipment": [
40 {
41 "Service": { "Code": "03", "Description": "UPS Ground" },
42 "TotalCharges": { "CurrencyCode": "USD", "MonetaryValue": "12.45" }
43 },
44 {
45 "Service": { "Code": "02", "Description": "UPS 2nd Day Air" },
46 "TotalCharges": { "CurrencyCode": "USD", "MonetaryValue": "28.99" }
47 }
48 ]
49 }
50}

Pro tip: UPS service codes: '03' = Ground, '02' = 2nd Day Air, '01' = Next Day Air Saver, '13' = Next Day Air Saver Early A.M. Keep these codes in your Bubble workflow notes for display name mapping.

Expected result: The UPS Get Rate Backend Workflow returns an array of shipping service options with prices. The checkout page in Bubble displays these options in a Repeating Group for the customer to select.

6

Trigger Workflows from the Frontend and Switch to Production

From the Bubble frontend (a button click, page load, or form submission), trigger the Backend Workflow using 'Schedule API Workflow' → select your Backend Workflow → pass the required parameters (tracking number, address fields, etc.). For tracking: add a 'Track' button to your order detail page. On click, trigger 'UPS Track Package' with the stored tracking number. After the Backend Workflow completes, the result is stored in a UPSTrackingResult Data Type or a Custom State — bind the tracking status display to this data. Before switching to production: 1. In UPS developer portal → My Apps → your app, get the PRODUCTION Client ID and Client Secret (separate from sandbox credentials) 2. Update the `ups_client_id` App Constant to the production Client ID 3. Update the `ups_client_secret` App Constant to the production Client Secret 4. Update the `ups_base_url` App Constant to `https://onlinetools.ups.com` 5. Clear any cached UPSToken records so the first production call mints a fresh production token Test with a real UPS tracking number from a recent shipment to verify the production credentials and base URL work together. The UPS tracking numbers in Sandbox documentation are test-only and will not resolve against `onlinetools.ups.com`.

production-switch-checklist.txt
1# Steps for switching from Sandbox to Production
2
3# 1. Update App Constant: ups_base_url
4# Sandbox: https://wwwcie.ups.com
5# Production: https://onlinetools.ups.com
6
7# 2. Update App Constants with production credentials:
8# ups_client_id production Client ID
9# ups_client_secret production Client Secret (Private)
10
11# 3. Clear cached tokens:
12# In Bubble, run a one-time workflow:
13# 'Make changes to all UPSToken where is_active = Yes'
14# set is_active = No
15
16# 4. Test with a real tracking number from a recent real UPS shipment
17# Production tracking numbers: 1Z + 16 characters (e.g., 1Z12345E0205271688)
18# Sandbox test numbers: see UPS developer portal Track API documentation

Pro tip: After switching to production, verify in Bubble's Logs tab → Server logs that the first token mint call hits `onlinetools.ups.com` (not `wwwcie.ups.com`). A successful 200 from the token endpoint with a non-empty `access_token` confirms the production credentials are correct.

Expected result: The tracking and rating flows work end-to-end from the Bubble frontend. Switching to production requires only App Constant updates — no workflow changes needed. A real UPS tracking number resolves successfully against the production API.

Common use cases

Package Tracking Status in a Bubble Order Dashboard

Display real-time UPS shipment status, location history, and estimated delivery date directly in a Bubble admin panel or customer-facing order page. Users enter a tracking number and the Bubble workflow calls the UPS Tracking API via a Backend Workflow, returning status and activity checkpoints.

Bubble Prompt

How do I build a Bubble page where users can enter a UPS tracking number and see the current shipment status, location, and estimated delivery date returned from the UPS Tracking API?

Copy this prompt to try it in Bubble

Carrier Rate Comparison at Checkout

At the shipping step of a Bubble checkout flow, call the UPS Rating API with the package dimensions, weight, and destination address to retrieve service options and prices. Display the results so the customer can choose between UPS Ground, 2-Day Air, and Next Day Air options.

Bubble Prompt

How do I call UPS's Rating API from a Bubble checkout workflow to get shipping rate options for a package, and display them as a selectable list for the customer?

Copy this prompt to try it in Bubble

Address Validation Before Shipping

Before creating a shipment or handing off to ShipStation/another fulfillment system, validate the customer's entered shipping address against UPS's Address Validation API to catch typos, incorrect zip codes, and undeliverable addresses before they cause failed deliveries.

Bubble Prompt

How do I validate a customer's shipping address using the UPS Address Validation API from a Bubble workflow, and surface the corrected address suggestion if the original is invalid?

Copy this prompt to try it in Bubble

Troubleshooting

401 'invalid_client' error from the UPS token endpoint

Cause: This error typically means the Client ID or Client Secret is incorrect, or you are using sandbox credentials against the production base URL (or vice versa). UPS issues separate credentials for sandbox (`wwwcie.ups.com`) and production (`onlinetools.ups.com`).

Solution: Verify that your App Constants match the environment: sandbox credentials + `wwwcie.ups.com`, or production credentials + `onlinetools.ups.com`. Do not mix. Regenerate credentials in the UPS developer portal if you suspect the secret was compromised. Also confirm the token endpoint body uses `application/x-www-form-urlencoded` encoding, not JSON.

UPS tracking endpoint returns data in sandbox but not in production

Cause: Sandbox tracking numbers (from UPS test documentation) only resolve against `wwwcie.ups.com`. They are not real packages and cannot be tracked on the production API. This is a common confusion at launch.

Solution: Use a real UPS tracking number from an actual shipment to test against the production API (`onlinetools.ups.com`). Sandbox test numbers from UPS documentation will return 404 or 'tracking number not found' on the production endpoint.

Backend Workflows tab is not visible in Bubble

Cause: Backend Workflows are only available on Bubble's paid plans. On the Free plan, the Backend Workflows tab does not appear in the Bubble editor.

Solution: Upgrade to a paid Bubble plan to unlock Backend Workflows. The UPS integration requires Backend Workflows to safely handle the Client Secret server-side. There is no secure alternative for this OAuth flow on the Free plan.

Token caching is not working — a new token is minted on every API call

Cause: The token validity check in the Backend Workflow is not correctly comparing `expiry_time` against the current time, or the UPSToken record is not being found because `is_active` is not set to Yes when the token is created.

Solution: In the Backend Workflow, add a condition at the start: 'Only when: Do a search for UPSToken where is_active is Yes and expiry_time > Current date/time → count is 0'. This condition makes the token-minting steps only run when no valid token exists. Ensure the UPSToken creation step sets `is_active` to Yes.

'There was an issue setting up your call' when initializing the Rating API call

Cause: The UPS Rating API requires a complete, valid JSON body with all required fields to return a successful test response for initialization. Missing or placeholder values in the body result in a 400 error from UPS, blocking Bubble's initialization.

Solution: Use the full sample request JSON from UPS developer documentation as your initialization body. Replace address fields with real postal codes (even if test ones) and set a valid package weight. The Rating API is strict about the request structure — incomplete bodies return cryptic 400 errors.

Best practices

  • Store the UPS Client Secret as a Private App Constant in Bubble. Private constants are inaccessible from client-side workflows and never appear in Bubble's debugger — equivalent to a server-side environment variable.
  • Cache the UPS Bearer token in a Bubble Data Type with an expiry timestamp. Minting a new token on every API call adds 300-500ms latency and risks unnecessary load on UPS's token endpoint. One token can serve hundreds of calls before expiring.
  • Keep sandbox and production credentials and base URLs clearly separated. Use App Constants (not hardcoded values in workflows) for both, so switching to production is a settings change rather than a workflow rebuild.
  • Design the Backend Workflow to check token validity before every UPS call: if the cached token is still valid, use it; if it has expired, mint a new one first. This pattern handles token expiry gracefully without requiring manual intervention.
  • Only request the UPS API products your app actually needs. Adding all products to your developer app does not grant access — each product must be explicitly enabled in the UPS developer portal.
  • Test the token refresh flow explicitly: let a cached token expire (or manually set its `expiry_time` to the past in Bubble's database) and verify the Backend Workflow correctly mints a new token and completes the API call.
  • In Bubble's Logs tab → Server logs, monitor the token endpoint calls during development to catch credential errors early. The `invalid_client` error from UPS is the most common first-run failure.
  • Set up Bubble Privacy rules on the UPSToken Data Type. The access token is a sensitive credential — restrict database read access to server-side (Backend Workflows) only, preventing logged-in users from querying it through the database.

Alternatives

Frequently asked questions

Why does the UPS API require a Backend Workflow in Bubble?

UPS uses OAuth 2.0 client credentials — you POST a Client Secret to get a Bearer token. The Client Secret must never appear in client-side code or network requests. Bubble's Backend Workflows run server-side, so storing the Client Secret as a Private App Constant and making the token call from a Backend Workflow keeps the secret completely off the browser.

Do I need a paid UPS account to use the API?

No — a UPS developer account at developer.ups.com is free. The API provides access to tracking and rating data at no charge. Actual shipping rates are determined by your UPS account contract, and label creation charges carrier fees, but API access itself is free.

Why does the UPS API work in development but not in production?

This almost always means you are still using sandbox credentials or the sandbox base URL (`wwwcie.ups.com`) in your production app. UPS has entirely separate credentials and base URLs for sandbox vs production. Update your Bubble App Constants: production credentials + `https://onlinetools.ups.com` as the base URL.

How often does the UPS Bearer token expire?

UPS tokens expire based on the `expires_in` value in the token response (returned in seconds). In practice this is often around 4 hours (14,400 seconds), but you should not hardcode an expiry duration. Instead, store the `expires_in` value from the response, calculate the expiry timestamp, and check it before each API call. If the token has expired, mint a new one.

Can I get UPS shipping rates without a paid UPS shipper account?

Yes — you can call the Rating API with your developer credentials to get retail UPS rates. However, negotiated (discounted) rates that a business receives through a UPS account contract are only available when the API calls are made with credentials linked to that business account. The rates returned will be retail/list prices without a linked business account.

Is the old UPS XML API still usable from Bubble?

The legacy UPS XML API still exists but is not recommended for new integrations. The modern REST API at developer.ups.com is the current standard with OAuth 2.0. If you find UPS documentation links pointing to different endpoint structures or WSDL files, those are the legacy XML endpoints — confirm you are on the REST API before building.

RapidDev

Talk to an Expert

Our team has built 600+ apps. Get personalized help with your project.

Book a free consultation

Integrations are where projects stall

We wire Bubble integrations like this one every week — auth, webhooks, edge cases included. Fixed-price builds from $13K, delivered in 6–10 weeks.

Talk to an integration engineer

We put the rapid in RapidDev

Need a dedicated strategic tech and growth partner? Discover what RapidDev can do for your business! Book a call with our team to schedule a free, no-obligation consultation. We'll discuss your project and provide a custom quote at no cost.