Help Debugging HTML Widget: migrate_values API Call Failing (404 Not Found from Widget, Works via cURL)

Hi Ubidots Community,

I’m working on an HTML Canvas widget to help me copy all historical data from one variable to another existing variable within my account (rather then using curl commands, etc)

Goal:
select a source variable and a target variable, then trigger a process to copy all dots between them.

What Works:

  • The widget successfully uses my API Token (BBUS-...) via fetch in JavaScript to make GET requests to /api/v2.0/devices/ (to list devices) and /api/v2.0/devices/{id}/variables/ (to list variables). This confirms the token is valid and has at least read permissions, and the base URL (https://industrial.api.ubidots.com/api/v2.0) is correct for my account type

  • I have a cURL command that successfully initiates the copy using the /devices/ endpoint and variable IDs:

    curl -v -X POST ‘https://industrial.api.ubidots.com/api/v2.0/devices/_/migrate_values/
    -H ‘Content-Type: application/json’
    -H ‘X-Auth-Token: API_TOKEN’
    -d ‘{ “from”: “SOURCE_VARIABLE_ID”, “to”: “TARGET_VARIABLE_ID” }’

    (This returns a 202 Accepted with a task ID when run from my terminal).

The Problem:
When my HTML widget tries to make the exact same POST request using JavaScript fetch to https://industrial.api.ubidots.com/api/v2.0/devices/_/migrate_values/ with the simple payload { "from": sourceVarId, "to": targetVarId } and the same API token in the X-Auth-Token header, the request fails.

The browser’s console log shows the request being made correctly, including the headers (X-Auth-Token, Content-Type: application/json), but the server responds with a 404 Not Found error.

Troubleshooting Steps Taken:

  1. Verified Endpoint and Payload: Ensured the widget uses the exact endpoint and payload structure that works in cURL.
  2. Verified Token: Confirmed the token works for GET requests within the same widget script.
  3. Verified Resources: Manually checked in Ubidots that both source and target variables exist.
  4. Checked Permissions: The token should have write permissions for the target, but the 404 error occurs before any potential permission-related validation error
  5. Tried Other Endpoints/Payloads: Previously attempted using the /api/v2.0/variables/_/migrate_values/ endpoint with various documented payload structures (using variables array, prefixed labels ~, etc.), which resulted in 400 Validation Error. Switching to the /devices/ endpoint (matching the working cURL) now results in this 404.

My Question:
Why would the POST /api/v2.0/devices/_/migrate_values/ endpoint return a 404 Not Found error when called via fetch from within an Ubidots HTML Canvas widget context, but work perfectly fine when called via cURL with the identical URL, payload, and token?

Are there any known limitations, CORS issues (though usually a different error), or specific requirements for calling this particular endpoint from a browser/widget environment? Is there a different endpoint or payload structure I should be using specifically for this widget context?

I’m happy to provide the full widget code if needed. Any insights would be greatly appreciated!

Thanks!

Hello @qntfy,

Could you please send me the dashboard and widget you’re using for testing?

Alejandro

I will DM you

Perfect

@qntfy I will not change anything on your code as you’re using the widget on a production environment. However, the problem is that you’re choosing variables ID’s on a devices endpoint.

In this case, from and to keys needs to contain one device ID, not a variable ID.

Look at the documentation, we need to use device ID’s.

Hey @alejomora7 that worked!

To be specific, I wanted to copy only the VARIABLE, and not the entire device… But the endpoint was poing to the DEVICE endpoint.

So I made the change and it works! Fantastic! Thank you for your help :slight_smile:

You’re welcome!