# JavaScript & fetch

> Post JSON to the endpoint from fetch, Axios or any HTTP client and handle the response yourself.

Source: https://docs.formclick.io/html-forms/javascript-fetch

If you want full control of the UI, skip the script and call the endpoint yourself. Send JSON with an `Accept: application/json` header and you get JSON back.

**fetch**

```js title="contact.js"
const form = document.querySelector('#contact');

form.addEventListener('submit', async (e) => {
  e.preventDefault();
  const data = Object.fromEntries(new FormData(form));

  const res = await fetch('https://api.formclick.io/submit', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json', Accept: 'application/json' },
    body: JSON.stringify({ access_key: 'YOUR_ACCESS_KEY', ...data }),
  });
  const result = await res.json();

  if (result.success) {
    form.reset();
    alert(result.message);
  } else {
    alert(result.message || 'Something went wrong');
  }
});
```

**FormData**

```js
// Send the form as-is (no JSON). Formclick parses multipart/form-data too.
const res = await fetch('https://api.formclick.io/submit', {
  method: 'POST',
  headers: { Accept: 'application/json' },
  body: new FormData(document.querySelector('#contact')),
});
const result = await res.json();
```

**Axios**

```js
import axios from 'axios';

const { data } = await axios.post('https://api.formclick.io/submit', {
  access_key: 'YOUR_ACCESS_KEY',
  name: 'Jane Smith',
  email: 'jane@example.com',
  message: 'Hello!',
});
// data → { success: true, message: "Thank you! Your message has been received." }
```

**cURL**

```bash
curl -X POST https://api.formclick.io/submit \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -d '{"access_key":"YOUR_ACCESS_KEY","name":"Jane","email":"jane@example.com","message":"Hi"}'
```

## Response

```json
{
  "success": true,
  "message": "Thank you! Your message has been received.",
  "redirect_url": "https://yourwebsite.com/thanks"   // only when a redirect applies
}
```

Errors use the same shape with `success: false` and a readable `message`. Always check `success` rather than only the HTTP status. The full list is in [Errors](https://docs.formclick.io/api-reference/errors).

> **Note:** CORS is open (`Access-Control-Allow-Origin: *`), so you can call the endpoint from any website or local development server.
