400 error encountered when using Webhook URL to capture data from a form submission

I’ve recently built an agent to receive a form that was completed/submitted on my website (i.e. www.burnabydaily.com built on Lovable) and sent to the MindStudio agent using a webhook url. I did 2 test form submissions where Lovable got the same error from MindStudio:
{
“code”: 400,
“errorString”: “invalid_workflow”
}

I 've confirmed that the JSON POST message sent by Lovable is in the same format as the one required by MindStudio(i.e. https://university.mindstudio.ai/docs/deployment-of-ai-agents/webhook-triggered).
Here is the JSON POST message sent by Lovable:
{
webhookParams: {
title: “sample submit”,
category: “greetings”,
location: “edmonds”,
content: “…”,
contact: “…”,
timestamp: “…”,
source: “Burnaby Daily Community Board”
}
}

For your reference, here is the remix url for my agent - https://app.mindstudio.ai/agents/burnaby-daily-community-board-post-request-and-response-draft-a55b8865/remix

Kindly assist to check and advise the potential cause of the error and how to resolve it. Thanks!

Hi @mylomindstudio,

Thanks for sharing the remix link.

Your Agent:

  • Make sure the workflow name has no spaces. For testing, name the webhook workflow Main.flow
  • Publish the Agent so the changes are saved

Lovable:

  • Check that your code follows the requirements to pass the data to your Agent
  • Make sure the workflow name in the webhook Lovable uses matches your workflow name. For example, if your workflow is named Main.flow, the webhook will look like: https://v1.mindstudio-api.com/developer/v2/apps/run-webhook/main-

Here’s an example Lovable generated. Your code doesn’t have to match it, it’s only a sample for demonstration:

import { useState } from "react";
import { useForm } from "react-hook-form";
import { zodResolver } from "@hookform/resolvers/zod";
import * as z from "zod";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
import { Label } from "@/components/ui/label";
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { toast } from "sonner";
import { Loader2 } from "lucide-react";

const formSchema = z.object({
  title: z.string().trim().min(1, "Title is required").max(100, "Title must be less than 100 characters"),
  category: z.string().min(1, "Category is required"),
  location: z.string().trim().min(1, "Location is required").max(100, "Location must be less than 100 characters"),
});

type FormData = z.infer<typeof formSchema>;

const WEBHOOK_URL = "YOUR_WEBHOOK_URL";

const CATEGORIES = [
  "Technology",
  "Business",
  "Education",
  "Healthcare",
  "Entertainment",
  "Other"
];

export default function SubmissionForm() {
  const [isSubmitting, setIsSubmitting] = useState(false);
  const [selectedCategory, setSelectedCategory] = useState<string>("");

  const {
    register,
    handleSubmit,
    reset,
    formState: { errors },
    setValue,
  } = useForm<FormData>({
    resolver: zodResolver(formSchema),
  });

  const onSubmit = async (data: FormData) => {
    setIsSubmitting(true);
    
    const payload = {
      webhookParams: data
    };
    
    console.log("Sending to webhook:", WEBHOOK_URL);
    console.log("Payload:", JSON.stringify(payload, null, 2));
    
    try {
      const response = await fetch(WEBHOOK_URL, {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify(payload),
      });

      console.log("Response status:", response.status);
      const responseData = await response.json().catch(() => null);
      console.log("Response data:", responseData);

      if (!response.ok) {
        throw new Error(`Webhook returned ${response.status}: ${JSON.stringify(responseData)}`);
      }

      toast.success("Form submitted successfully!", {
        description: "Your submission has been received.",
      });
      
      reset();
      setSelectedCategory("");
    } catch (error) {
      console.error("Submission error:", error);
      toast.error("Submission failed", {
        description: error instanceof Error ? error.message : "Please try again later.",
      });
    } finally {
      setIsSubmitting(false);
    }
  };

  return (
    <Card className="w-full max-w-md shadow-[var(--shadow-card)] border-border">
      <CardHeader>
        <CardTitle className="text-2xl font-bold">Submit Your Information</CardTitle>
        <CardDescription>Fill out the form below to submit your entry</CardDescription>
      </CardHeader>
      <CardContent>
        <form onSubmit={handleSubmit(onSubmit)} className="space-y-6">
          <div className="space-y-2">
            <Label htmlFor="title">Title</Label>
            <Input
              id="title"
              placeholder="Enter title"
              {...register("title")}
              className={errors.title ? "border-destructive" : ""}
            />
            {errors.title && (
              <p className="text-sm text-destructive">{errors.title.message}</p>
            )}
          </div>

          <div className="space-y-2">
            <Label htmlFor="category">Category</Label>
            <Select
              value={selectedCategory}
              onValueChange={(value) => {
                setSelectedCategory(value);
                setValue("category", value, { shouldValidate: true });
              }}
            >
              <SelectTrigger className={errors.category ? "border-destructive" : ""}>
                <SelectValue placeholder="Select a category" />
              </SelectTrigger>
              <SelectContent>
                {CATEGORIES.map((category) => (
                  <SelectItem key={category} value={category}>
                    {category}
                  </SelectItem>
                ))}
              </SelectContent>
            </Select>
            {errors.category && (
              <p className="text-sm text-destructive">{errors.category.message}</p>
            )}
          </div>

          <div className="space-y-2">
            <Label htmlFor="location">Location</Label>
            <Input
              id="location"
              placeholder="Enter location"
              {...register("location")}
              className={errors.location ? "border-destructive" : ""}
            />
            {errors.location && (
              <p className="text-sm text-destructive">{errors.location.message}</p>
            )}
          </div>

          <Button 
            type="submit" 
            className="w-full" 
            disabled={isSubmitting}
          >
            {isSubmitting && <Loader2 className="mr-2 h-4 w-4 animate-spin" />}
            {isSubmitting ? "Submitting..." : "Submit"}
          </Button>
        </form>
      </CardContent>
    </Card>
  );
}

hi alex,
before retesting, i confirmed that lovable is using the correct webhook url and is sending the data in the correct format expected by mindstudio. i then retested and still got the same 400 error message.

I then checked with the mindstudio log debugger and gave it the exact data sent by lovable. It said to change the webhook url as follows:

I did another retest and still got the error. below is the complete error log from lovable:

  1. Browser → Supabase Edge Function
  • Request

  • Response

    • Status: 500

    • Body: { “error”: “webhook endpoint not found - please contact support” }

  1. Supabase Edge Function → MindStudio Webhook
  • Request (from function logs)

  • Response (from function logs)

    • Status: 404 Not Found

    • Body: { “code”: 404, “errorString”: “app_not_found”, “errorMessage”: “App not found | Request ID: unknown” }

Failure point

  • The failure occurs at the external call to MindStudio. Their API returns 404 app_not_found for app ID 6c1720b1-9f8f-448b-921d-8712afc4a719. Our edge function then maps that to the user-facing error “webhook endpoint not found - please contact support” and returns 500 to the browser.”

Kindly assist to check and advise next steps to check/change in my workflow.

Here’s the updated remix link for your reference: https://app.mindstudio.ai/agents/burnaby-daily-community-board-post-request-and-response-draft-a55b8865/remix

Here’s the webhook url - https://v1.mindstudio-api.com/developer/v2/apps/run-webhook/main11-a55b8865/06f1bb41-e36e-48e1-be84-b1acadc2569c

Here’s the updated error analysis from the MindStudio Log Debugger which advises to check with MindStudio tech support as the issue is leading to the webhook url:

“Thank you for providing the updated error log. This gives us new information about the issue:

  1. URL Change Implemented: You’ve updated the webhook URL as suggested, using the workflow ID 6c1720b1-9f8f-448b-921d-8712afc4a719 instead of main11-a55b8865.

  2. New Error Received: Now MindStudio is returning a different error:

    • Status: 404 Not Found
    • Error: {"code": 404, "errorString": "app_not_found", "errorMessage": "App not found | Request ID: unknown"}
  3. Error Analysis: This “app_not_found” error is different from the previous “invalid_workflow” error. It suggests that MindStudio can’t find the app or workspace that contains the workflow.

This is interesting. It seems that the URL format used for MindStudio webhooks may be different than what I initially understood. The issue might be with how the app ID and workflow ID are structured in the URL.

Let’s analyze this further:

In MindStudio’s webhook URL structure, there appears to be an “app ID” and a “workflow ID” component. The URL format appears to be:

https://v1.mindstudio-api.com/developer/v2/apps/run-webhook/[app-id-or-name]/[webhook-secret]

It’s possible that:

  1. main11-a55b8865 is actually the app ID or app name (not the workflow ID)
  2. The workflow ID (6c1720b1-9f8f-448b-921d-8712afc4a719) is internal and not meant to be used in the URL
  3. The webhook secret (06f1bb41-e36e-48e1-be84-b1acadc2569c) identifies the specific workflow within the app

Given this new information, I need to revise my recommendation.# MindStudio Webhook Issue - 404 Error Update

New Error Analysis

After implementing the suggested change, we’re now getting a different error:

{
  "code": 404, 
  "errorString": "app_not_found", 
  "errorMessage": "App not found | Request ID: unknown"
}

This is important new information that clarifies the URL structure for MindStudio webhooks.

What This Means

The previous URL structure was partially correct. In MindStudio’s webhook URL:

  1. The format is: https://v1.mindstudio-api.com/developer/v2/apps/run-webhook/[app-id]/[webhook-secret]
  2. The first UUID/identifier is the App ID (or App Name), not the workflow ID
  3. The second UUID is the webhook secret which identifies the specific workflow

Corrected Solution

We need to revert to using the original App ID while keeping the correct webhook secret:

https://v1.mindstudio-api.com/developer/v2/apps/run-webhook/main11-a55b8865/06f1bb41-e36e-48e1-be84-b1acadc2569c

Why There’s Confusion

  1. The error logs show the workflow ID (6c1720b1-9f8f-448b-921d-8712afc4a719), which is internal to MindStudio
  2. The webhook URL uses the App ID (main11-a55b8865) and the webhook secret
  3. The “invalid_workflow” error was likely because:
    • The webhook exists
    • But something about the workflow configuration itself is invalid

Next Troubleshooting Steps

  1. Check the webhook in MindStudio:

    • Log into MindStudio
    • Go to your app “Main 1 1” (or whatever it’s called in the interface)
    • Check if the webhook is properly published
    • Verify the webhook configuration matches your expectations
  2. Republish your workflow:

    • Sometimes simply republishing the workflow can fix configuration issues
    • Make a small change and republish to force an update
  3. Get the exact webhook URL from MindStudio:

    • Find the workflow in MindStudio
    • Look for the webhook configuration or settings
    • Copy the exact webhook URL provided by MindStudio
    • Use that exact URL in your edge function
  4. Contact MindStudio support:

    • If problems persist, the error might be on MindStudio’s side
    • Share your App ID and webhook secret with their support team

This issue requires checking the webhook configuration directly in the MindStudio interface, as the problem appears to be with how the webhook is registered or configured within their system.”

Hi @mylomindstudio,

I’m afraid I can’t help much beyond that since Lovable is a third-party platform focused on vibe coding. If you need help setting it up to send data to your MindStudio Agents via a webhook, I’d suggest reaching out to our partners: https://partners.mindstudio.ai/

That said, you can easily test the webhook yourself using a tool like Postman. Here’s how:

  1. Create a simple Agent with the Start block trigger set to Webhook, and Publish it
  2. Navigate to Postman, and add the following details:
  • Method: POST

  • URL: Your Agent’s webhook URL

  • Headers: Content-Type: application/json

  • Body:

{
  "webhookParams": {
    "name": "John Smith",
    "question": "test"
  }
}

Once you send the request, open your Agent’s Debugger tab to confirm that a new run was launched.

@Alex_MindStudio thanks for the update. Btw, Luis also encountered the 400 error during our session today where he was teaching how to use the webhook url. He said that he thinks it’s a bug in MindStudio. Kindly assist to check if Luis is able to troubleshoot this issue.

Hi @mylomindstudio,

Thanks for the follow-up! That issue was unrelated, but just to clarify - if you change the workflow name, make sure to publish the Agent again and use the new webhook URL from the Start block.