Quick Start Guide

Let’s Cook Up Some Personalization!

Welcome to Growcado — your new favorite way to show the right content to the right people (without losing your mind). In this quick start, we’re gonna create a recipe that can shapeshift depending on who’s looking at it.

Imagine this: You’ve got a tasty lasagna recipe. But some folks are into veggies 🌱, while others dream about cheese-pulling meaty goodness 🍖. With Growcado, you can create one recipe and serve the perfect version to each person. Neat, right?

👨‍🍳 What We’re Cooking

We’re building a Recipe content type, which lets us add all the tasty details about a dish. Then we’ll use Growcado's personalization magic to serve:

  • A vegan lasagna to customers who prefer plant-based meals 🥬

  • A classic meat lasagna to those who love the carnivore life 🐮

No forks required yet — we’re just prepping the ingredients.

📋 Prerequisites

Before we dive in, make sure you have these ready:

Growcado Account & Studio Access

You'll need access to Growcado Studio to create content types and set up audience segments.You'll Don't have an account? Fill out our form or send us an email and we'll create one for you ASAP! 🚀

Development Environment

Any environment that can make HTTP requests — whether you're building web apps with React/Vue/Angular, mobile apps with React Native/Flutter, server-side projects with Node.js, or adding personalization to an existing project.

All you need: A way to consume APIs and handle JSON responses. That's pretty much everything these days! ✨

🧱 1- Content Type Structure (a.k.a. Our Recipe Blueprint)

Before we dive in, let’s clear something up: a content type is like a blueprint — it defines what kind of data you’ll store and how it’s structured. Think of it as the mold for your content. For example, a “Recipe” content type might have fields like name, image, and ingredients. Once you’ve got that set, you can start adding actual content, like a lasagna recipe, a chocolate cake recipe, or your grandma’s mystery stew. The content type doesn’t hold specific recipes — it just tells the system what every recipe should look like.

Here’s how our recipe content is structured:

  • Name (text): What are we cooking? “Lasagna”, obviously.

  • Image (media): A delicious photo to make people drool.

  • Ingredients (reference): A list of ingredients, like pasta, tomato sauce, or vegan cheese.

Inside each Ingredient, we’ve got:

  • Name (text): Like "Tofu" or "Mozzarella".

  • Amount (text): Maybe "200g" or “a sprinkle.”

This setup gives us superpowers — we can mix and match different ingredient sets (like meat vs. vegan), and plug them into the same recipe layout.

🛠️ Step-by-Step: Building the Content Types

Let’s roll up our sleeves and set up the content types we need: Recipe and Ingredient. You'll only have to do this once — think of it like prepping your pantry before the cooking starts.

🧄 Step 1: Create the Ingredient content type

Head to the Content Type Builder and click “+ New”.

  • Model Name: Ingredient

  • Description: "Stores individual ingredients with their name and amount. Used inside recipes to build full ingredient lists."

  • Model Identifier: ingredient (automatically filled)

➡️ Don’t forget to click Save once you're done filling it out.

Creating the Ingredient content type with name, description, and identifier.

✍️ Step 2: Add your first field — Name

Click Add Field, and you’ll see a list of field types.

  • Choose the Text field

  • Set Field Name to Name

  • Mark it as required (because even the humblest of onions needs a name)

Choosing the Text field type — the first field we’ll use.
Configuring the Name field as a required text input.

➡️ Once done, click Save to lock in the field.

🧪 Step 3: Add the Amount field

Add another Text field called Amount.

  • Example values: “200g”, “2 cups”, “a dash”

  • Same flow as the previous one

➡️ Hit Save when finished.

🥘 Step 4: Create the Recipe content type

With your ingredients ready, let’s create a new content type: Recipe.

  • Model Name: Recipe

  • Description: "Use this to create recipes with name, image, and a list of ingredients."

  • Model Identifier: recipe

➡️ Yep, you guessed it — click Save.

Creating the Recipe content type with a description and model identifier.

✏️ Step 5: Add the Name field

Just like you did for Ingredient, add a Text field called Name.

🖼️ Step 6: Add the Image field

Choose the Media field to add a photo to your recipe.

  • Field Name: Image

  • Yes, it’s required — people eat with their eyes first.

➡️ Click Save when you're done.

Adding an image field to upload a photo of the recipe.
  • Choose the Reference field

  • Name it Ingredients

  • Limit accepted content types to Ingredient so only real food shows up here

Linking ingredients to the recipe using a reference field.

✅ Step 8: Final check

At the end, your Recipe should have:

  • Name (Text)

  • Image (Media)

  • Ingredients (Reference to Ingredient)

Final structure of the Recipe content type with all fields in place.

🥘 2- Creating the Content Entries

Now that your content types are set, it’s time to create some real entries — like filling your digital kitchen with actual food. We'll start with adding ingredients and then create the classic version of our Lasagna recipe (no personalization yet — we’re saving the fun stuff for the next round 😏).

🧄 Step 1: Add Your Ingredients

Head to the Content section in the sidebar and select Ingredient. Click the big, beautiful + Add Entry button.

No ingredients yet — let’s add some!

Start with your first ingredient, for example:

  • Name: Lasagna Noodles

  • Amount: 9 sheets

Don’t forget to hit Save & Publish when done!

Creating a single ingredient entry.

Repeat this process to add the rest:

  • Tomato Sauce – 500ml

  • Mozzarella Cheese – 200g

  • Ground Beef – 300g

  • Vegan Ricotta – 250g

  • Vegan Mozzarella – 200g

All six ingredients published and ready to use.

🍽️ Step 2: Create the Lasagna Recipe

Now that we’ve stocked the pantry, it’s time to cook.

Head back to Content, switch to the Recipe tab, and hit + Add Entry.

  • Name: Lasagna

  • Image: Upload a delicious photo of lasagna (bonus points if it makes your users hungry)

Here's a neat trick: we can change the auto-generated Content ID to something more readable — like lasagna — by clicking the Content ID field in the right menu. We did exactly that so it’s easier to reference this content later on.

Filling in the recipe details — name and image first

Step 3: Add Ingredients to the Recipe

Scroll down to the Ingredients field and click Add Existing Content. This will open a list of all the ingredients you just created. Select the ones that belong in this version of the recipe.

➡️ Finally, click Save & Publish. Boom — you’ve got your first recipe online!

📡 3- Getting Your Content via API

Alright, your content is cooked, published, and ready to serve — but how do you actually get it into your app or website? That’s where Growcado’s API comes in.

When you’re viewing a content entry (like our Lasagna recipe), just look at the sidebar on the right. Under the “Link” section, you’ll find the full API URL already built for you — including your tenant, model, and identifier.

Copy it, paste it, call it. Boom. 🍝

Let’s take a look at how to fetch the classic Lasagna recipe using a simple GET request.

curl 'https://api.growcado.io/cms/tenant/{tenantId}/published/{modelIdentifier}/{identifier}'
Param
Required
Description

tenantId

Your project’s unique tenant ID

modelIdentifier

The content type you’re fetching — for our case, recipe

identifier

The unique content ID you set earlier — in our case, lasagna

🔍 What You Get Back

When you call the API, here's exactly what the response looks like for our Lasagna recipe: Don't panic when you see this response — it might look like a lot at first glance, but it's actually super straightforward once you know what you're looking at.

{
  "id": "32226494780751473240104532705280",
  "modelIdentifier": "recipe",
  "identifier": "lasagna",
  "fields": [
    {
      "identifier": "name",
      "type": "TEXT",
      "value": ["Lasagna"]
    },
    {
      "identifier": "image", 
      "type": "MEDIA",
      "value": ["https://api.growcado.io/storage/api/184549109729170412"]
    },
    {
      "identifier": "ingredients",
      "type": "REFERENCE", 
      "value": [
        {
          "id": "32226492677280317212325595578368",
          "modelIdentifier": "ingredient",
          "identifier": "58a42cb8-48b1-42",
          "fields": [
            {
              "identifier": "name",
              "type": "TEXT", 
              "value": ["Mozzarella Cheese"]
            },
            {
              "identifier": "amount",
              "type": "TEXT",
              "value": ["200g"]
            }
          ]
        },
        {
          "id": "32226492453750652613221511331840",
          "modelIdentifier": "ingredient", 
          "identifier": "e105ac68-9b40-47",
          "fields": [
            {
              "identifier": "name",
              "type": "TEXT",
              "value": ["Ground Beef"]
            },
            {
              "identifier": "amount", 
              "type": "TEXT",
              "value": ["300g"]
            }
          ]
        },
        {
          "id": "32226491725652835616848097574912",
          "modelIdentifier": "ingredient",
          "identifier": "95270311-4f17-47", 
          "fields": [
            {
              "identifier": "name",
              "type": "TEXT",
              "value": ["Tomato Sauce"]
            },
            {
              "identifier": "amount",
              "type": "TEXT", 
              "value": ["500ml"]
            }
          ]
        },
        {
          "id": "32226484768957203194547015778304",
          "modelIdentifier": "ingredient",
          "identifier": "bb4b4597-a34a-49",
          "fields": [
            {
              "identifier": "name", 
              "type": "TEXT",
              "value": ["Lasagna Noodles"]
            },
            {
              "identifier": "amount",
              "type": "TEXT",
              "value": ["9 sheets"]
            }
          ]
        }
      ]
    }
  ]
}

🧠 Understanding the Response Structure

Notice how the response is structured:

  • Top level: Contains the main content metadata (id, modelIdentifier, identifier)

  • Fields array: Each field has an identifier, type, and value array

  • Reference fields: When you reference other content (like ingredients), the full nested objects come back automatically

  • Values are arrays: Even single values come wrapped in arrays — this keeps the structure consistent

💻 Quick Integration Example

async function fetchRecipe(recipeId) {
  const response = await fetch(`https://api.growcado.io/cms/tenant/YOUR_TENANT_ID/published/recipe/${recipeId}`);
  const recipe = await response.json();
  
  // Get the recipe name
  const name = recipe.fields.find(f => f.identifier === 'name').value[0];
  
  // Get the image URL
  const imageUrl = recipe.fields.find(f => f.identifier === 'image').value[0];
  
  // Parse ingredients with their name and amount
  const ingredientsData = recipe.fields.find(f => f.identifier === 'ingredients').value;
  const ingredients = ingredientsData.map(ingredient => {
    const name = ingredient.fields.find(f => f.identifier === 'name').value[0];
    const amount = ingredient.fields.find(f => f.identifier === 'amount').value[0];
    return { name, amount };
  });
  
  return { name, imageUrl, ingredients };
}

// Example usage:
fetchRecipe('lasagna').then(recipe => {
  console.log(recipe.name); // "Lasagna"
  console.log(recipe.ingredients); 
  // [
  //   { name: "Mozzarella Cheese", amount: "200g" },
  //   { name: "Ground Beef", amount: "300g" },
  //   { name: "Tomato Sauce", amount: "500ml" },
  //   { name: "Lasagna Noodles", amount: "9 sheets" }
  // ]
});

🎯 4- Time for the Magic: Adding Personalization

Now comes the fun part! Remember how we promised you could serve vegan lasagna to plant-lovers and meaty goodness to carnivores? Let's make that happen.

The secret sauce is audience segments — these let you define rules that automatically sort your visitors into groups based on how they found you, what device they're using, or other criteria. When someone visits your site, Growcado checks if they match any of your segment rules and serves them the right content version.

Here's what we are going to build: if someone clicks a link from a vegan blog to reach your lasagna recipe, they'll automatically see the plant-based ingredient list. Everyone else gets the classic meat-and-cheese version.

Ready to get personal? Let's cook! 👨‍🍳

👥 Create Your First Audience

We're going to start by creating a segment for visitors who come from vegan websites. These are folks who probably found your site through vegan recipe blogs, plant-based cooking sites, or health-focused referrers.

🏷️ Setting Up the "Vegans" Segment

Head over to the Audience section in your sidebar and click + Add Segment.

You'll see a friendly 2-step process:

Step 1: Metadata (Set name and description)

  • Segment Name: Plant-Based Visitors

  • Description: Visitors who arrive from vegan recipe blogs and plant-based websites

Keep the description clear — future you (and your team) will thank you when you have 20+ segments!

➡️ Hit Next when you're ready to get specific.

🎯 Define Who Belongs

Now for the targeting magic! This is where you tell Growcado exactly who should be considered a "Vegan" visitor.

In the Context section, you'll build rules like this:

Who [are] [visiting through a] [UTM Source] [vegan.shop]

Here's what this means in plain English:

  • Who are: We're defining people who match certain criteria

  • visiting through a: They came to your site via a specific channel

  • UTM Source: The tracking parameter that shows where they came from

  • vegan.shop: The specific source value (like a vegan recipe blog or plant-based store)

🔗 Real-World Example

Let's say you partner with a popular vegan blog called "PlantPowerRecipes.com". When they link to your lasagna recipe, the URL might look like:

https://yoursite.com/recipes/lasagna?utm_source=vegan.shop

Anyone clicking that link gets automatically tagged as part of your "Plant-Based Visitors" segment. Smart, right?

🪄 Creating Content Variants

Now that you've got your "Vegans" audience segment set up, it's time for the real magic — creating different versions of your lasagna recipe that automatically show up for different people.

Think of variants like having multiple recipe cards for the same dish. Your default recipe has ground beef and mozzarella, but your vegan variant swaps those out for plant-based alternatives. Same delicious lasagna, different ingredients based on who's looking!

🔄 Step 1: Create a Vegan Variant

Head back to your Lasagna recipe in the Content section. You'll see your current ingredient list with all the meaty, cheesy goodness. At the bottom, there's a magical little button called + Add Variant.

Click that button — it's time to create some personalized magic! ✨

🎯 Step 2: Choose Your Target Audience

A modal will pop up with a simple 2-step process:

First, choose your content variant (vegan ingridients in this case)

Second, Choose Segment, this is where you pick who gets this variant

You'll see your "Vegans" segment right there, complete with the description you wrote earlier: "Visitors who arrive from vegan recipe sites and plant-based cooking blogs"

Select the Vegans segment and hit Save.

Beautiful! Now you've got a dedicated vegan version. Notice how Growcado has cleverly organized everything:

Variant 1: 👥 Vegans This is where you added the plant-based ingredients.

  • Vegan Mozzarella

  • Vegan Ricotta

  • Tomato Sauce (this one stays the same!)

  • Lasagna Noodles (also the same)

Default value: 🌐 For other users This shows your original ingredients that everyone else will see:

  • Mozzarella Cheese

  • Ground Beef

  • Tomato Sauce

  • Lasagna Noodles

🎉 What Just Happened?

You've just created personalized content! Here's how it works:

  • Vegan blog visitor clicks a link with utm_source=vegan.shop → Gets the plant-based ingredient list

  • Everyone else visits normally → Gets the classic meat-and-cheese version

  • Same recipe, same API call → Growcado automatically serves the right version

🚀 Test It Out

Let's go back to our integration code from earlier and add personalization to it! Remember those multi-language examples? Now they can automatically serve different content:

async function fetchRecipe(recipeId, userContext = {}) {
  const headers = {};
  
  // Add UTM header based on user context (referrer, user preferences, etc.)
  if (userContext.utmSource) {
    const utmParams = new URLSearchParams();
    if (userContext.utmSource) utmParams.append('source', userContext.utmSource);
    if (userContext.utmCampaign) utmParams.append('campaign', userContext.utmCampaign);
    if (userContext.utmMedium) utmParams.append('medium', userContext.utmMedium);
    
    headers['X-UTM'] = utmParams.toString();
  }
  
  const response = await fetch(`https://api.growcado.io/cms/tenant/YOUR_TENANT_ID/published/recipe/${recipeId}`, {
    headers
  });
  const recipe = await response.json();
  
  // Get the recipe name
  const name = recipe.fields.find(f => f.identifier === 'name').value[0];
  
  // Get the image URL
  const imageUrl = recipe.fields.find(f => f.identifier === 'image').value[0];
  
  // Parse ingredients with their name and amount
  const ingredientsData = recipe.fields.find(f => f.identifier === 'ingredients').value;
  const ingredients = ingredientsData.map(ingredient => {
    const name = ingredient.fields.find(f => f.identifier === 'name').value[0];
    const amount = ingredient.fields.find(f => f.identifier === 'amount').value[0];
    return { name, amount };
  });
  
  return { name, imageUrl, ingredients };
}

// Real-world usage examples:

// 1. Regular visitor (gets default version)
const recipe = await fetchRecipe('lasagna');
console.log('Default ingredients:', recipe.ingredients);

// 2. User came from a vegan blog
const veganUser = {
  utmSource: 'vegan.shop',
  utmCampaign: 'recipe-share',
  utmMedium: 'blog'
};
const veganRecipe = await fetchRecipe('lasagna', veganUser);
console.log('Vegan ingredients:', veganRecipe.ingredients);

// 3. Detect from current page URL parameters
const urlParams = new URLSearchParams(window.location.search);
const currentUserContext = {
  utmSource: urlParams.get('utm_source'),
  utmCampaign: urlParams.get('utm_campaign'),
  utmMedium: urlParams.get('utm_medium')
};
const contextualRecipe = await fetchRecipe('lasagna', currentUserContext);

🌟 You've Just Scratched the Surface

Congratulations! You've just built your first personalized content system that automatically detects vegan-interested visitors and serves appropriate content without any code changes.

But here's where it gets really exciting — what we just did was the simplest possible example. We used basic UTM source detection to keep this intro digestible, but Growcado's audience targeting is incredibly sophisticated. You can create mind-blowingly precise segments using three powerful categories:

🎯 Customer Context (What we just used)

Beyond UTM parameters, target users based on:

  • Location: Show regional ingredients ("Show tikka masala spices to users in the UK")

  • Time intelligence: Different content for breakfast vs dinner hours, holidays vs regular days

  • Language & locale: Automatic localization without managing separate content

  • Custom headers: Send any data from your app to trigger personalization

👤 User Attributes (The real power)

Sync rich user data from anywhere and personalize based on demographics, subscription tiers, purchase history, interests, and more:

  • CRM systems: Salesforce, HubSpot, Pipedrive — sync customer profiles and subscription data

  • Analytics platforms: Segment, Mixpanel, Google Analytics — leverage behavioral insights

  • Data warehouses: Snowflake, BigQuery, Redshift — tap into your entire data ecosystem

  • E-commerce platforms: Shopify, WooCommerce, Stripe — use purchase history and preferences

  • Customer platforms: Intercom, Zendesk, Klaviyo — incorporate support and communication data

  • Any API or database: Custom integrations to pull user attributes from anywhere

🧠 User Behaviors (Coming Soon)

Target users based on their actions and patterns:

  • Search patterns: Mark users as "health-conscious" if they search for low-calorie recipes

  • Content engagement: Show advanced recipes to users who spend time reading detailed instructions

  • Navigation behavior: Detect recipe preferences from browsing patterns

  • Cross-session learning: Build user profiles that get smarter over time

🔥 Beyond Variants: One-to-One Hyper Personalization

But wait, there's more! Beyond swapping entire ingredient lists, you can make any text field hyper-personalized with live JavaScript expressions:

  • Recipe titles: "${profile.firstName}'s Perfect ${profile.dietaryPreference} Lasagna"

  • Serving suggestions: "This recipe serves ${profile.familySize} people perfectly"

  • Personal touches: "Welcome back ${profile.firstName}! Since you loved our ${profile.lastFavoriteRecipe}, you'll love this one"

Every piece of content becomes dynamically personal — in real-time! 🤯

🚀 Real-World Examples

Imagine these scenarios — all possible with the same simple API you just learned:

// Same fetchRecipe() function, but now it can:

// Show premium wine pairings to Gold subscribers from your CRM
const premiumUser = { userTier: 'gold', interests: ['wine'] };

// Display halal ingredients to Muslim users in the Middle East  
const regionalUser = { location: 'UAE', dietaryNeeds: ['halal'] };

// Recommend quick recipes to busy parents on weekday evenings
const timeContext = { timeOfDay: 'evening', dayOfWeek: 'tuesday', hasKids: true };

The best part? Your integration code stays exactly the same. One API call, infinite personalization possibilities.

Hungry for more? Our complete documentation serves up advanced targeting, enterprise integrations, and real-world case studies that'll transform how you think about personalization. Bon appétit! 👨‍🍳

🚀 Where to Go Next

If you're building with JavaScript/TypeScript, check out our official SDK that handles all the UTM tracking, referrer detection, and header management automatically. What took us several lines of manual code becomes a simple GrowcadoSDK.getContent() call with built-in personalization, automatic customer journey tracking, SSR support, and zero configuration. The SDK doesn't just make integration easier — it makes advanced personalization effortless! 🍽️✨

Last updated