Contact Form Submission Api Issue

Hi everyone,
I have encountered a problem on working shopify contact form using in react Hydrogen component that form integrate with form submission api //forms.shopifyapps.com/api/v2/form_submission starting working fine but now facing unauthorized issue code(401).

<------------------code--------------------------->
import {useNavigate} from ‘@remix-run/react’;
import React, {useEffect, useState} from ‘react’;
import {DEFAULT_FORM_DATA, FORM_API} from ‘~/constant/form’;
import HCaptcha from ‘@hcaptcha/react-hcaptcha’;
import { useShopifyContext } from ‘~/store/context’;

const ContactForm = () => {
const navigate = useNavigate();
const {formId, storeDomain} = useShopifyContext();
// Form State
const [formData, setFormData] = useState(DEFAULT_FORM_DATA);
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const [success, setSuccess] = useState<string | null>(null);
const [captchaResponse, setCaptchaResponse] = useState(‘’);
useEffect(() => {
if (captchaResponse) console.log(hCaptcha Token: ${captchaResponse});
}, [captchaResponse]);

// Handle form field changes
const handleChange = (
e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement>,
) => {
const {name, value} = e.target;
setFormData((prev: any) => ({
…prev,
[name]: value,
}));
};

// :white_check_mark: OnSubmit function with API call
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setLoading(true);
setError(null);
setSuccess(null);

// ✅ JSON payload structure
const payload = {
  form_instance_id: formId,
  h_captcha_response: captchaResponse,
  shopify_domain: storeDomain,
  'custom#message': formData.message,
  email: formData.email,
  first_name: formData.name,
  phone_number: formData.phone,
};

console.log(payload);
try {
  const response = await fetch(FORM_API, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      'Authorization': `Bearer YOUR_ACCESS_TOKEN`, // Include your API token if required
    },
    body: JSON.stringify(payload),
  });

  console.log(response);

  if (response.ok) {
    setSuccess('Form submitted successfully!');
    setFormData({
      name: '',
      email: '',
      phone: '',
      message: '',
      h_captcha_response: '',
    });
    // setTimeout(() => navigate('/'), 2000);
  } else setError(`Failed to submit form. Status: ${response.status}`);
} catch (e) {
  console.log(e);
  setError('An error occurred. Please try again.');
} finally {
  setLoading(false);
}

};

return (

  <div className="contact-form text-white p-8">
    <h2 className="text-2xl font-bold mb-4">Contact Us</h2>

    {/* ✅ Form with API onSubmit handler */}
    <form onSubmit={handleSubmit} method="POST" className="space-y-6">
      {error && <p className="text-red-500">{error}</p>}
      {success && (
        <p className="text-green-500 text-center p-2">{success}</p>
      )}

      <div className="form-in">
        <div className="ConName">
          <label htmlFor="name" className="block text-sm font-medium">
            Name
          </label>
          <input
            id="name"
            name="name"
            type="text"
            value={formData.name}
            onChange={handleChange}
            placeholder="Your name"
            required
            className="mt-1 block w-full px-4 py-2 border rounded-md text-black"
          />
        </div>

        <div className="ConEmail">
          <label htmlFor="email" className="block text-sm font-medium">
            Email
          </label>
          <input
            id="email"
            name="email"
            type="email"
            value={formData.email}
            onChange={handleChange}
            placeholder="Your email"
            required
            className="mt-1 block w-full px-4 py-2 border rounded-md text-black"
          />
        </div>
      </div>

      <div>
        <label htmlFor="phone" className="block text-sm font-medium">
          Phone
        </label>
        <input
          id="phone"
          name="phone"
          type="tel"
          value={formData.phone}
          onChange={handleChange}
          placeholder="Your phone number"
          className="mt-1 block w-full px-4 py-2 border rounded-md text-black"
        />
      </div>

      <div>
        <label htmlFor="message" className="block text-sm font-medium">
          Message
        </label>
        <textarea
          id="message"
          name="message"
          rows={5}
          value={formData.message}
          onChange={handleChange}
          placeholder="Your message"
          required
          className="mt-1 block w-full px-4 py-2 border rounded-md text-black"
        />
      </div>

      {/* ✅ Hidden hCaptcha field */}
      <HCaptcha
        sitekey="f06e6c50-85a8-45c8-87d0-21a2b65856fe"
        onVerify={setCaptchaResponse}
      />
      <input
        style={{display: 'none'}}
        id="h_captcha_response"
        name="h_captcha_response"
        type="text"
        value={formData.h_captcha_response}
        onChange={handleChange}
      />
      <div className="flex">
        <button
          type="submit"
          className="bg-blue-500 hover:bg-blue-700 text-white font-bold py-2 px-4 rounded"
          disabled={loading}
          onSubmit={() => handleSubmit}
        >
          {loading ? "Submitting..." : "Submit"}
        </button>
        <button
          type="button"
          onClick={() => navigate("/")}
          className="bg-gray-500 hover:bg-gray-700 text-white font-bold py-2 px-4 ml-2 rounded"
        >
          Back
        </button>
      </div>
    </form>
  </div>
</div>

);
};

export default ContactForm;
<--------------end code------------------------>
Request URL:

Request Method:

POST

Status Code:

401 Unauthorized

Remote Address:

185.146.173.20:443

Referrer Policy:

strict-origin-when-cross-origin

Response:
{“message”:“Authentication failed”,“errors”:null}
please look into this.

Hi! Do you have your access token set up? ‘Authorization’: Bearer YOUR_ACCESS_TOKEN

Hi Balint,
Thank u for your reply
before i don’t use bearer token working fine but now facing on error.

Hi, meanwhile I contacted the form submission API developers, and they said form submissions are only exposed to be used by the theme app extension, so this endpoint is not supported to be used from hydrogen. Sorry for that :frowning:

Any other way to implement.please give me suggestion.

One potential solution is to use metaobjects to store contact form entries, see example here: GitHub - juanpprieto/hydrogen-contact-form-metaobject: Hydrogen basic contact form using a custom metaobject and the Admin API