Skip to main content
Solved

how to use form element to post member to a List

  • March 31, 2022
  • 7 replies
  • 2132 views

Forum|alt.badge.img+2

I want use a html form element to submit the subscribers like this:

<form action="https://a.klaviyo.com/api/v2/list/VMd343/members?api_key=U12345" method="post" target="_blank">
<input type="email" name="EMAIL" placeholder="Email">
<button type="submit">Sign In</button>
</form>

But when I test to submit the form, I got an error:

{"detail":"CSRF Failed: <HttpResponseForbidden status_code=403, \"text/html\">"}

Does the development API not be supported in Frontend?

Could anyone give a hand? thanks a lot!

Best answer by Dov

Hi @jeremyfix,

Thanks for sharing this with us.

You are correct, that endpoint has to be executed server side.

The base URL to use is https://manage.kmail-lists.com/ajax/subscriptions/subscribe which will add a user's email (and additional user properties) to any list in Klaviyo. 

This is different than the normal subscribe URL used in Klaviyo's own forms. Below is a break down of POST body properties to pass.

  • g (required) - LIST_ID
  • email (required) - User's email address
  • $fields (optional) - This tells the Klaviyo backend which keys (additional users properties) to expect in the POST request. All properties (other than email) need to be passed as a value under $fields and as it's own key.
  • $list_fields (optional) - This inherits form the $fields but would then would take a list of data and transpose it as a custom property in list format
  • other properties (optional) - For each property in $fields, you want to pass a key/value pair like below:
    • $first_name: John
    • $last_name: Smith
    • Custom Property 1: Custom Value 1

    • Custom Property 2: Custom Value 2
      var settings = {
      "async": true,
      "crossDomain": true,
      "url": "https://manage.kmail-lists.com/ajax/subscriptions/subscribe",
      "method": "POST",
      "headers": {
      "content-type": "application/x-www-form-urlencoded",
      "cache-control": "no-cache"
      },
      "data": {
      "g": "{{LIST_ID}}",
      "$fields": "$first_name,$last_name,Favorite Color,Favorite Book,$source",
      "email": "{{email}}",
      "$first_name": "{{first_name}}",
      "$last_name": "{{last_name}}",
      "Favorite Color": "{{favorite_color}}",
      "Favorite Book": "{{favorite_book}}",
      "$source": "Custom Form"
      }
      }
      $.ajax(settings).done(function (response) {
      console.log(response);
      });

      The snippet above uses {{ }} placeholder syntax, which will need to be altered for your platform. The important part is that product fields are dynamically rendered based on which product page you're viewing.

Response

200 Success: Request was successful
400 BAD REQUEST: This happens when the email already exists.
405 METHOD NOT ALLOWED: required fields missing from the POST request

Special Properties

$first_name, $last_name, and $source are special Klaviyo properties. Here is a list of all Special Klaviyo Properties for Users:

  • $id - your unique identifier for a person
  • $email - email address
  • $first_name - first name
  • $last_name - last name
  • $phone_number - phone number$
  • $title -title at their business or organization
  • $organization - business or organization they belong to
  • $city - city they live in
  • $region - region or state they live in
  • $country - country they live in
  • $zip - postal code where they live
  • $image - url to a photo of the person
  • $source - What form the user signed up with

I hope that helps.

7 replies

Dov
Forum|alt.badge.img+61
  • Klaviyo Alum
  • 1493 replies
  • Answer
  • April 1, 2022

Hi @jeremyfix,

Thanks for sharing this with us.

You are correct, that endpoint has to be executed server side.

The base URL to use is https://manage.kmail-lists.com/ajax/subscriptions/subscribe which will add a user's email (and additional user properties) to any list in Klaviyo. 

This is different than the normal subscribe URL used in Klaviyo's own forms. Below is a break down of POST body properties to pass.

  • g (required) - LIST_ID
  • email (required) - User's email address
  • $fields (optional) - This tells the Klaviyo backend which keys (additional users properties) to expect in the POST request. All properties (other than email) need to be passed as a value under $fields and as it's own key.
  • $list_fields (optional) - This inherits form the $fields but would then would take a list of data and transpose it as a custom property in list format
  • other properties (optional) - For each property in $fields, you want to pass a key/value pair like below:
    • $first_name: John
    • $last_name: Smith
    • Custom Property 1: Custom Value 1

    • Custom Property 2: Custom Value 2
      var settings = {
      "async": true,
      "crossDomain": true,
      "url": "https://manage.kmail-lists.com/ajax/subscriptions/subscribe",
      "method": "POST",
      "headers": {
      "content-type": "application/x-www-form-urlencoded",
      "cache-control": "no-cache"
      },
      "data": {
      "g": "{{LIST_ID}}",
      "$fields": "$first_name,$last_name,Favorite Color,Favorite Book,$source",
      "email": "{{email}}",
      "$first_name": "{{first_name}}",
      "$last_name": "{{last_name}}",
      "Favorite Color": "{{favorite_color}}",
      "Favorite Book": "{{favorite_book}}",
      "$source": "Custom Form"
      }
      }
      $.ajax(settings).done(function (response) {
      console.log(response);
      });

      The snippet above uses {{ }} placeholder syntax, which will need to be altered for your platform. The important part is that product fields are dynamically rendered based on which product page you're viewing.

Response

200 Success: Request was successful
400 BAD REQUEST: This happens when the email already exists.
405 METHOD NOT ALLOWED: required fields missing from the POST request

Special Properties

$first_name, $last_name, and $source are special Klaviyo properties. Here is a list of all Special Klaviyo Properties for Users:

  • $id - your unique identifier for a person
  • $email - email address
  • $first_name - first name
  • $last_name - last name
  • $phone_number - phone number$
  • $title -title at their business or organization
  • $organization - business or organization they belong to
  • $city - city they live in
  • $region - region or state they live in
  • $country - country they live in
  • $zip - postal code where they live
  • $image - url to a photo of the person
  • $source - What form the user signed up with

I hope that helps.


Forum|alt.badge.img+2
  • Author
  • Contributor I
  • 1 reply
  • April 2, 2022

Forum|alt.badge.img+1
  • Contributor I
  • 1 reply
  • June 15, 2023

Hi @jeremyfix, the tutorial you shared above is no longer available, any chance you could give me a few details on where to implement the code? I’m trying to subscribe to my newsletter all visitors that sign up for an account on my shop. 

Thanks a lot! 😊


Brian Turcotte
Forum|alt.badge.img+37
  • Klaviyo Alum
  • 1393 replies
  • June 15, 2023

Hi @sophiedupau!

 

Here’s a Community thread where I discuss the contents of that original tutorial:

 

Best,

Brian


Forum|alt.badge.img+2
  • Contributor II
  • 3 replies
  • November 7, 2025

Hi everyone 👋

I’m trying to subscribe users to a Klaviyo list using the frontend API on my Shopify site.

Here’s what I’m doing:

I have a custom form with an name, email, phone fields and a checkbox for marketing consent.

When the user checks the box, I want to include consent in the API request.

I’m using the https://manage.kmail-lists.com/ajax/subscriptions/subscribe endpoint (not the server-side one).

Here’s a simplified version of my code:

$(document).ready(function () {

const form = document.querySelector('#email_signup');

const formBlock = document.querySelector('.black-friday-form_wrapper-form-block');

const successMessage = document.querySelector('.black-friday-form_wrapper-form_succes-message');

const errorMessage = document.querySelector('.black-friday-form_wrapper-form-error-message');

const submitButton = form.querySelector('button[type="submit"]');

const buttonMainText = submitButton.querySelector('span:first-child');

const originalButtonText = buttonMainText.textContent;

 

$('#email_signup').on('submit', function (e) {

e.preventDefault();

 

submitButton.disabled = true;

buttonMainText.textContent = 'Please wait...';

successMessage.style.display = 'none';

errorMessage.style.display = 'none';

 

console.log('form submitted!');

var name = $('#first_name').val();

var phone = $('#phone_number').val();

var email = $('#email').val();

 

var settings = {

async: true,

crossDomain: true,

url: "https://manage.kmail-lists.com/ajax/subscriptions/subscribe",

method: "POST",

headers: {

"content-type": "application/x-www-form-urlencoded",

"cache-control": "no-cache"

},

data: {

"g": "LIST _ID", // replace LIST_ID with id of list to be subscribed

"email": email,

"$fields": "$first_name, $phone_number",

"$first_name": name,

"$phone_number": phone

}

};

 

$.ajax(settings).done(function (response) {

buttonMainText.textContent = originalButtonText;

submitButton.disabled = false;

 

form.style.display = 'none';

successMessage.style.display = 'block';

form.reset();

});

});

});


My question is:

Should I use $consent: 'email' or $consent: true when the user checks the marketing box?

Is $consent supported when using the frontend endpoint?

Or do I need to handle consent differently (e.g. as a custom property)?

Any clarification or official documentation link would be super helpful 

Thanks,
Abid


Byrne C
Community Manager
Forum|alt.badge.img+27
  • Community Manager
  • 574 replies
  • November 12, 2025

Hi ​@abidarif,

While the https://manage.kmail-lists.com/ajax/subscriptions/subscribe method may technically work, this endpoint is no longer supported, and we recommend using the new v3 client-side endpoint, Create Client Subscription. The linked document for this provides the structure you’ll need, but as an example, you’d want to structure the subscriptions section of it like so: 

"subscriptions": {
"email": {
"marketing": {
"consent": "SUBSCRIBED"
}
}
}

 


Forum|alt.badge.img+2
  • Contributor II
  • 3 replies
  • November 15, 2025

Thanks for the update!

Just to confirm — are these new v3 subscription endpoints backend-only, or can they also be used on the frontend inside Shopify?

And if they can be used client-side, what would be the correct request structure? A simple example JSON body would really help make sure I’m doing it the right way.