Issue: HTTP 400 on Uploading Linked volumeMesh Element via /v2alpha/elements

Issue: HTTP 400 on Uploading Linked volumeMesh Element via /v2alpha/elements

walsh.kevin
Contributor Contributor
200 Views
6 Replies
Message 1 of 7

Issue: HTTP 400 on Uploading Linked volumeMesh Element via /v2alpha/elements

walsh.kevin
Contributor
Contributor

Hi Forma team,

We are building a Grasshopper–Forma integration using the REST API and encountering a persistent issue when trying to register a mesh element via POST /v2alpha/elements. Here's a breakdown of the issue and what’s been confirmed to work:


Working Steps

  1. Auth:
    Using a valid 3-legged OAuth2 token with data:read and data:write scopes
    → This same token works to create proposals and query project data.
  2. Step 1 – Get Upload Link:
    GET /forma/integrate/v1alpha/upload-link?authcontext={project_id}
    → Returns a valid blobId and presigned S3 URL.
  3. Step 2 – Upload Mesh to S3:
    A JSON mesh payload is successfully uploaded via PUT to the provided S3 URL. No error is returned.
  4. Step 3 – Register Mesh Element:
    A POST is sent to:
    https://developer.api.autodesk.com/forma/integrate/v2alpha/elements?authcontext={project_id}
    → This returns:

General Error: HTTP Error 400: Bad Request

  1. ...with no message in the response body.

Final Payload Sent to /v2alpha/elements

{
  "rootElement": {
    "properties": {
      "name": "mesh001",
      "category": "building"
    },
    "representations": {
      "volumeMesh": {
        "type": "linked",
        "blobId": "integrate:eyJzM0lkIjoiNmQ4ZjYwMTgtZjMxMC00ZmRkLWFjZmEtMmUwOTYwNWFkNzBjIn0="
      }
    }
  }
}
  • category: "building" is documented as valid.
  • The blobId is returned by Forma’s own upload-link call.
  • volumeMesh with "type": "linked" follows the exact example format in the Forma API docs.

My Questions

  1. Is this payload structure still supported?
  2. Are there any undocumented constraints on category, representationType, or blobId?
  3. Does the linked mesh need to reference an existing proposal or base explicitly?
  4. Should I be using a different representation type?

Debug Data (From Script Output)

DEBUG Upload URL:
https://integrate-api-payload-741408923162-eu-west-1-prod.s3... (truncated)

DEBUG Blob ID:
integrate:eyJzM0lkIjoiNmQ4ZjYwMTgtZjMxMC00ZmRkLWFjZmEtMmUwOTYwNWFkNzBjIn0=

DEBUG Mesh Payload:
{"mesh": {"key": "mesh001", "vertices": [[236.24, -180.76, 84.52], ... ]}}

DEBUG Register URL:
https://developer.api.autodesk.com/forma/integrate/v2alpha/elements?authcontext=pro_t8eh95fmlm

DEBUG Headers:
{
  "Authorization": "Bearer eyJhbGci... (truncated)",
  "X-Ads-Region": "EMEA",
  "Content-Type": "application/json"
}

DEBUG Final Element Payload:
{
  "rootElement": {
    "properties": {
      "name": "mesh001",
      "category": "building"
    },
    "representations": {
      "volumeMesh": {
        "type": "linked",
        "blobId": "integrate:eyJzM0lkIjoiNmQ4ZjYwMTgtZjMxMC00ZmRkLWFjZmEtMmUwOTYwNWFkNzBjIn0="
      }
    }
  }
}

Let me know if you need full response headers or a sample mesh payload for context.
Thanks so much in advance!

201 Views
6 Replies
Replies (6)
Message 2 of 7

syed_ammar_abbas_naqvi
Autodesk
Autodesk

Hi @walsh.kevin,

Thanks for reaching out! It is awesome to see you build with Forma APIs.

I can see two main issues causing your HTTP 400 error with the /v2alpha/elements endpoint. 

Issue #1: Payload Structure (V2 API Change)

You're using V1 payload structure with the V2 API. The V2 API removed the rootElement wrapper.

Your current payload:

{
  "rootElement": {
    "properties": {"name": "mesh001", "category": "building"},
    "representations": {
      "volumeMesh": {"type": "linked", "blobId": "integrate:eyJ..."}
    }
  }
}

Correct V2 structure:

{
  "properties": {"name": "mesh001", "category": "building"},
  "representations": {
    "volumeMesh": {"type": "linked", "blobId": "integrate:eyJ..."}
  }
}


Issue #2: Mesh Format for volumeMesh (Critical)

Your uploaded S3 payload is JSON mesh data:

{"mesh": {"key": "mesh001", "vertices": [[236.24, -180.76, 84.52], ... ]}}

However, volumeMesh representations must be GLB files (binary GLTF format), not JSON mesh data. From the official documentation:

"The link should point to a GLB file, containing the binary version of GLTF."

Hope this helps! Let me know if you need clarification on any of these points.

Message 3 of 7

walsh.kevin
Contributor
Contributor

 

Hi Ammar,

Thanks for your help - your clarification on the volumeMesh requirements and the v2 payload structure was spot on, and we were able to successfully upload a .glb file and register it as a volumeMesh element via the /v2alpha/elements endpoint.

The API call returns a successful response and a valid element URN, so from a backend perspective, everything seems to complete as expected.

 

However, the issue we’re now facing is, the uploaded mesh is not visible anywhere in the Forma UI - not in the proposal view, not in any layer or element list, and not selectable in the model.

Here’s what we’ve confirmed:

• The GLB itself is valid (opens correctly in external GLTF viewers)

• The geometry is a simple box, centered around the origin and properly scaled

• It was exported from Rhino and registered with category: "building" (I've also tried "massing")

• The registration response includes a proper integrate: URN and no errors

 

Despite this, the geometry does not appear in the proposal — even when zoomed out. There’s also no visible “elements” list or UI indicator that the upload was successful from the user side.

I’ve also confirmed the element is being created by trying to call GET /v2alpha/elements to list what's registered in the project, but strangely that endpoint returns:

jsonCopyEdit{"error": "IncompleteSignatureException"}

 

— which seems like an AWS-specific error unrelated to this type of request.

Would you be able to clarify:

1. Should volumeMesh elements appear in the UI today, or are they registered but hidden by default?

2. Are there constraints or steps needed to “place” or “activate” a linked mesh in the proposal once registered?

3. Is there a known issue with GET /v2alpha/elements failing via 3-legged OAuth?

Let me know if you'd like our project ID, element URN, or GLB file for reference — happy to provide those.

Thanks again,

Kevin

0 Likes
Message 4 of 7

syed_ammar_abbas_naqvi
Autodesk
Autodesk

Hi @walsh.kevin,

Thanks for the follow-up! Great to hear that the GLB conversion and V2 payload structure fixes resolved your HTTP 400 error.

I can help you solve the new issues you're experiencing. The problems you're facing relate to how Forma's API architecture works - you need one additional step for element visibility.

Issue #1: Elements Not Visible in Forma UI (MISSING STEP)

Root Cause: Creating an element via the Integrate API only stores it in the backend. For visibility, you need either Library OR Proposal integration depending on your use case.

Choose Your Visibility Approach:

1. Create GLB and upload to S3 (you've done this)
2. Create element via Integrate API (you've done this)
3. ADD TO LIBRARY || OR  || ADD TO PROPOSAL:

Option A: ADD TO LIBRARY (for user-draggable catalog):

curl -v 'https://developer.api.autodesk.com/forma/library/v1alpha/library-items?authcontext=pro_t8eh95fmlm' \
  -X 'POST' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'X-Ads-Region: EMEA' \
  -H 'Content-Type: application/json' \
  -d '{
        "elementUrn": "YOUR_ELEMENT_URN",
        "name": "mesh001", 
        "status": "success"
      }'

Result: Element appears in Library panel, users can drag it into the scene

Option B: ADD TO PROPOSAL (for direct 3D scene placement):

curl -v 'https://developer.api.autodesk.com/forma/proposal/v1alpha/proposals/{proposalUrn}?authcontext=pro_t8eh95fmlm' \
  -X 'PUT' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'X-Ads-Region: EMEA' \
  -H 'Content-Type: application/json' \
  -d '{
        "name": "Updated Proposal",
        "terrain": {
          "urn": "EXISTING_TERRAIN_URN",
          "key": "terrain-key"
        },
        "base": {
          "urn": "EXISTING_BASE_URN", 
          "key": "base-key"
        },
        "children": [
          {
            "urn": "YOUR_ELEMENT_URN",
            "key": "mesh001-key",
            "name": "mesh001"
          }
        ]
      }'

Result: Element appears directly in the 3D scene/proposal

Issue #2: GET /v2alpha/elements Endpoint Error (ENDPOINT DOESN'T EXIST)

Root Cause: There is no GET /v2alpha/elements endpoint in the Forma API. That's why you're getting "IncompleteSignatureException" - AWS returns this error when you try to access non-existent routes.

Forma API Architecture:

  • Integrate API (/forma/integrate/) - Write-only (create/update elements)
  • Element Service API (/forma/element-service/) - Read-only (retrieve elements)
  • Library API (/forma/library/) - Catalog management
  • Proposal API (/forma/proposal/) - 3D scene composition

Correct endpoints to verify your element exists:

# Get a specific element by URN:
curl -v 'https://developer.api.autodesk.com/forma/element-service/v1alpha/elements/YOUR_ELEMENT_URN?authcontext=pro_t8eh95fmlm' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'X-Ads-Region: EMEA'

# Or get multiple elements in a batch:
curl -v 'https://developer.api.autodesk.com/forma/element-service/v1alpha/elements-batch?authcontext=pro_t8eh95fmlm' \
  -X 'POST' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'X-Ads-Region: EMEA' \
  -H 'Content-Type: application/json' \
  -d '{
        "urns": ["YOUR_ELEMENT_URN"]
      }'

Which Option Should You Choose?

Use Library API if:

  • You want users to manually place elements in the scene
  • You're building a catalog of reusable assets
  • You want interactive drag-and-drop functionality

Use Proposal API if:

  • You want elements to appear immediately in the 3D scene
  • You're programmatically composing a scene
  • You want direct placement without user interaction

For your Grasshopper integration, you'll likely want Option B (Proposal API) for immediate visibility.

Getting Proposal Information

To add elements to a proposal, you'll need to:

# List existing proposals to get URN and structure:
curl -v 'https://developer.api.autodesk.com/forma/proposal/v1alpha/proposals?authcontext=pro_t8eh95fmlm' \
  -H 'Authorization: Bearer YOUR_TOKEN' \
  -H 'X-Ads-Region: EMEA'

Let me know how this goes! Either approach should solve your visibility issue completely.

Reference Documentation:

0 Likes
Message 5 of 7

walsh.kevin
Contributor
Contributor

Hi Ammar,

Thanks again for your detailed explanation — it was extremely helpful in getting us unstuck.

We successfully completed the flow using the Library API method: the GLB was uploaded, registered, and then added to the project library via POST /library/v1alpha/library-items. The element appeared in the Library panel and we were able to place it manually in the scene — so that path is working great.

However, we ran into consistent issues trying to follow the Proposal API route. Specifically, when we attempted to add the element directly into a proposal using:

bashCopyEditPUT /forma/proposal/v1alpha/proposals/{proposalId}?authcontext=pro_t8eh95fmlm

…we consistently received this error:

jsonCopyEdit{"error": "IncompleteSignatureException"} 

This appears to be an AWS S3-style error, even though we’re not interacting with S3 at this step. Our payload was valid (with terrain, base, and children), and the token worked for all previous steps — including upload, element registration, and even the library insertion — so we don’t believe this is an auth issue.

Is there any chance this endpoint has specific constraints when used with 3-legged OAuth, or is being routed incorrectly through an AWS-signed layer internally?

Happy to share logs or run further tests. We’re very close to full automation and would love to resolve this last visibility step via the Proposal API if possible.

- Kevin

0 Likes
Message 6 of 7

syed_ammar_abbas_naqvi
Autodesk
Autodesk

Hi @walsh.kevin,

Excellent progress! Great to hear the Library API approach is working well and that also confirms your element creation workflow is working as intended.

I'm afraid I accidentally posted the wrong URL for the update endpoint in my previous reply. Here's the correct approach for the Proposal API:

Complete Working Workflow

Step 1: Get current proposal to find the revision ID and existing content:

GET https://developer.api.autodesk.com/forma/proposal/v1alpha/proposals/{proposalId}?authcontext={projectId}
Authorization: Bearer {token}
X-Ads-Region: EMEA

Step 2: Update the proposal, preserving existing terrain/base and adding your elements:

PUT https://developer.api.autodesk.com/forma/proposal/v1alpha/proposals/{proposalId}/revisions/{revisionId}?authcontext={projectId}
Authorization: Bearer {token}  
X-Ads-Region: EMEA
Content-Type: application/json

{
  "terrain": {existing terrain from Step 1},
  "base": {existing base from Step 1},
  "children": [
    ...{existing children from Step 1},
    {
      "key": "your-new-element-key",
      "element": "urn:adsk-forma-elements:integrate:pro_xxxxx:your-element-id:1",
      "transform": [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
    }
  ]
}


I'd recommend consulting the Proposal API documentation to double-check the exact endpoint structure and payload format.

0 Likes
Message 7 of 7

walsh.kevin
Contributor
Contributor

Hi Ammar,

Thanks again for the clarification on the correct Proposal API flow — we’ve updated our integration accordingly and are now using the PUT /revisions/{revisionId} structure exactly as described.

We’ve confirmed the following:

  • GLB is uploading successfully via the upload-link + S3 PUT method
  • The element is registered correctly via /v2alpha/elements, and returns a valid URN
  • We’re then retrieving the proposal’s current revision, terrain, base, and children
  • Our PUT to /proposals/{proposalId}/revisions/{revisionId} returns 200 OK, and includes the new element URN in children

However, despite the successful response, the new element is still not appearing in the 3D scene. We've verified that:

  • The transform is identity (no offset or scaling)
  • The element URN is valid
  • No error is returned by the API, and the revision appears to accept the update

We’re wondering now if there’s something subtle missing — such as a required property, status flag, or potential caching delay on the proposal side?

Interestingly, the same element appears immediately when added to the project via the Library API, so the mesh itself seems fine.

Any thoughts on how we can confirm whether the revision is referencing the element correctly, or whether there’s an additional propagation step needed for proposal visibility?

Thanks again for your help — we’re getting very close.

Best regards,

0 Likes