[ Contentful ] data-model

Content entries, media assets, and settings for localizing content into different languages.

Content Model > Content Type Id

Content type properties
All content types have standard fields that contain basic information about the content type, its fields and meta data.

Field Type Description

  • sys      (Type: Sys) Common system properties
  • name (Type: String) Name of the content type
  • description (Type: String) Description of the content type
  • fields (Type: [Field]) List of fields
  • displayField (Type: String) ID of main field used for display

 

Fields
Each content type -> set of up to 50 fields that you define, these fields can be one of the following, and correspond to a JSON type. There are differences between the fields you can create in the web app and the API.

 

  • Text (Short)

API type / JSON type : Symbol / String

Description : A short text field for titles and names

Max length : 256

Example : “The title”

  • Text (Long) : Fields do not support ordering or strict equality

API type / JSON type : Text / String

Description : A long text field for paragraphs of text. Filterable via full-text search

Max length : 50,000

Example : “This is a post and …”

  • Number (Integer)

API type / JSON type : Integer / Number

Description : A whole number

Limit : -2**53 – 2**53

Example : 42

  • Number (Decimal)

API type / JSON type : Number / Number

Description : A decimal number

Limit : -2**53 – 2**53

Example : 3.14

  • Date and time : Fields must be ISO8601 formatted, but do not require a time portion

API type / JSON type : Date / String

Description : A date and time in ISO 8601 format

Example : “2015-11-06T09:45:27”

  • Location

API type / JSON type : Location / Object

Description : Coordinate values for storing the latitude and longitude of a location

Example : {“lat”: 52.5208, “lon”: 13.4049}

  • Boolean

API type / JSON type : Boolean / Boolean

Description : For values that have two states, e.g. “yes” or “no”, “true” or “false”

Example : true

  • Media

API type / JSON type : Link / Object

Description : A link to an asset. The type of the referenced item is defined by the “linkType” property

Links guide : https://www.contentful.com/developers/docs/concepts/links/

  • Reference

API type / JSON type : Link / Object

Description : A link to another entry. The type of the referenced item is defined by the linkType property

Links guide : https://www.contentful.com/developers/docs/concepts/links/

  • Array

API type / JSON type : Array / Array

Description : List of values

Fields can contain multiple values with the Array type. An array can contain symbols (strings up to 256 characters), or links ( https://www.contentful.com/developers/docs/concepts/links/ ) to other entries or assets. The items property defines the allowed values in the array.

Array of symbols:

{
  "id": "tags",
  "type": "Array",
  "items": { "type": "Symbol" }
}

Array of assets:

{
  "id": "relatedImages",
  "type": "Array",
  "items": {
    "type": "Link",
    "linkType": "Asset"
  }
}

Array of links to items:

"reference_field": {
  "en-US": [
    {
      "sys": {
        "type": "Link",
        "linkType": "Asset",
        "id": "id1"
      }

     },
    {
       "sys": {
         "type": "Link",
         "linkType": "Asset",
         "id": "id2"
       }

     }
...
]
}

Individual fields also contain metadata, such as validations and widget appearance

Contentful stores individual items of content as entries, which represent textual /or structural information based on the content type used. Items can also be assets, which are binary files, such as images, videos or documents. Assets have three fixed fields, the name, description and attached file.

JSON preview tab

JSONpreview

To hide fields from appearing in JSON output, “… > Disable in Response

disableInResponse.png

This is useful for content information that is important to writers and editors, but not for public consumption.

 

Limited : by entry size

Example : [“name1”, “name2”, …]

  • JSON Object

API type / JSON type : Object / Object

Description : For storing any other types of objects you have defined

Limited : by entry size

Example : {“foo”: “bar”}

 

Links

Links are a powerful way to model relationships between content. You can use a URI query parameter with the Contentful search to retrieve an entire chain of related content to display in your application.

Entries can have link fields which point to other entries or assets, for example:

  • restaurant – linking to -> its menu (singular relationship)
  • menu – linking to -> its specific menu items (plural relationship)
  • Each menu item – linking to -> a photo (attachment)
  • restaurant – linking to -> multiple photos (attachments)

A single HTTP request lets you retrieve the entire set of linked resources above, starting with the menu, in one request. Contentful’s CDN can cache these requests to further speed up future requests. This is useful for mobile apps as it reduces the need for multiple concurrent connections, and the latency for results to return.

Links bring you other features:

  • Relationships are clearly defined and validated by specific content type fields.
  • Entry links can be validated by content type. E.g. Only allow Menu Items for fields.menuItems
  • Asset links can be validated by file type. E.g. Only allow Images for fields.photo

 

Link level ( https://www.contentful.com/developers/docs/concepts/links/ )

  • By default, a response includes the first level of linked content. Use the include parameter to set the number of levels you want to return
  • maximum number of inclusions is 10

Link resolution works regardless of how many results are there in items

Note: Only links between entries, spaces and assets are resolved. Links between spaces and content types are not included in the response.

JSON response
In the JSON response of a successful query, linked items are placed in the includes array, when not already fetched in the items array.

curl -v 'https://cdn.contentful.com/spaces/oc3u7dt7mty5/entries?access_token=6cabb22c95d52aa7752fe70ae9b3271a1fc2decf7ae7d99ccd7dceba718980e6&include=1'

 

"items": [
{
"sys": {
"type": "Entry",
"id": "2UmoQ8Bo4g4S82WmGiQIQE",
...
},
"fields": {
"name": "Spaceburger", //
"description": "The Jetson's love to come here!",
"restaurantImages": [ // restaurantImages linking field
{
"sys": {
"type": "Link",
"linkType": "Asset",
"id": "23qqdlTciMGm6IYy224euu" // link to imageId
}
}
]
}
},

...
],

 

"includes": { // includes array
"Asset": [
{
"sys": {
"type": "Asset", //
"id": "23qqdlTciMGm6IYy224euu", //
...
},
"fields": {
"title": "The SpaceBurger Photo",
"file": {
"fileName": "spaceburger.jpg",
"contentType": "image/jpeg",
"details": {
"image": {
"width": 550,
"height": 421
},
"size": 205683
},
"url": "//images.ctfassets.net/oc3u7dt7mty5/23qqdlTciMGm6IYy224euu/85514b430c28045a3b2930ebe15dfcce/spaceburger.jpg"
}
}
},
...
]
}

Before resolving links to items, Contentful matches the filter conditions of a query. This changes the response contained within the items array to reflect the search criteria of the querying URL.

Here’s the response for a menu linked to its meals:

"items": [ // array
{
"sys": {
"type": "Entry", //
"id": "4rJn9OJsBiAKmeoiiw40Ko",
},
"fields": {
"name": "Menu for Humans", //
...
"stickiness": 999.3,
"menuMeal": [
{
"sys": {
"type": "Link",
"linkType": "Entry",
"id": "3HkMtbj6hqcMYEqWIOm6SQ"
}
},
{
"sys": {
"type": "Link",
"linkType": "Entry",
"id": "3SVh6Ei9pCkkIkoE0ME4Ms"
}
}
]
}
},
...
{
"sys": {
"type": "Entry",
"id": "3HkMtbj6hqcMYEqWIOm6SQ",
...
},
"fields": {
"weight": 203.1,
"name": "AstroChicken ", //
"rating": 100,
"description": "An entire chicken with Andromeda's sauce"
}
},
{
"sys": {
"type": "Entry", //
"id": "3SVh6Ei9pCkkIkoE0ME4Ms",
...
},
"fields": {
"weight": 23049950.9,
"name": "AstroCattle", //
"rating": 30,
"description": "Yummy Cows with fries and Ketchup"
}
},
...

]

As AstroChicken and AstroCattle all match the conditions of the query parameters and are linked to Menu for Humans, they are all fetched in the same items array. Since AstroChicken and AstroCattle are present in the response’s items, they are not included in the includes.Entry array.

 

Fetching resources linked to a specific entry
You might want retrieve all items linked to a particular target entry. Your query URL should filter entries based on their specific content_type, a linking_field to link items and a entry_id from the target entry.

For example, to retrieve all resources of content type Menu linked to the restaurant Space Burger by using the following query URL:

curl -v 'https://cdn.contentful.com/spaces/oc3u7dt7mty5/entries?access_token=6cabb22c95d52aa7752fe70ae9b3271a1fc2decf7ae7d99ccd7dceba718980e6&content_type=3HjHXUYR3yyosUqAGmi8wu&fields.restaurantField.sys.id=2UmoQ8Bo4g4S82WmGiQIQE'

Because these are all Menus linked to the Space Burger restaurant, Menu for Humans, Menu for Romulans and Menu for Klingons are all retrieved alongside their own links and the target entry:

"items": [
{
"fields": {
"restaurantField": {
"sys": {
"type": "Link",
"linkType": "Entry",
"id": "2UmoQ8Bo4g4S82WmGiQIQE"
}
},
"name": "Menu for Humans",
"images": [
...
],
"menuMeal": [
...
]
},
"sys": {
"type": "Entry",
"id": "4rJn9OJsBiAKmeoiiw40Ko",
}
},
{
"fields": {
"restaurantField": {
"sys": {
"type": "Link",
"linkType": "Entry",
"id": "2UmoQ8Bo4g4S82WmGiQIQE"
}
},
"name": "Menu for Romulans",
"menuMeal": [
...
]
},
"sys": {
"type": "Entry",
"id": "2Mt2YctJQ4am8u2oI4kcsS",
...
}
},
{
"fields": {
"restaurantField": {
"sys": {
"type": "Link",
"linkType": "Entry",
"id": "2UmoQ8Bo4g4S82WmGiQIQE"
}
},
"name": "Menu for Klingons",
"menuMeal": [
{
...
}
]
},
"sys": {
"type": "Entry",
"id": "2RnAOt0ssgQ6kIk0E4WAeq",
...
}
},
{
"sys": {
"type": "Entry",
"id": "2UmoQ8Bo4g4S82WmGiQIQE",
...
},
"fields": {
"name": "Spaceburger",
"description": "The Jetson's love to come here!",
"restaurantImages": [
{
"sys": {
"type": "Link",
"linkType": "Asset",
"id": "23qqdlTciMGm6IYy224euu"
}
}
]
}
},
...
]

Modeling Relationship : Linking an entry to another entry

{
"fields": {
"reference_field": {
"en-US": {
"sys": {
"type": "Link",
"linkType": "Entry",
"id": ""
}
}
},
"title": {
...
},
...
}
}

Here’s a restaurant linked to its menu:

{
"sys": {
"type": "Entry",
"id": "il-doges"
},
"fields": {
"menu": {
"en-US": {
"sys": {
"type": "Link",
"linkType": "Entry",
"id": "il-doges-nice-menu"
}
}
}
}
}

 

Multiple links

It’s possible to create circular links, for example a chain of entries to model a dialog in a video game or complex graphs.

Certain fields in every Resource’s sys array are also links. These include the space they’re in, their content type (in the case of entries) or users who created or modified them.

An entry can link to more than one entry or asset, here’s how:

  • Multiple link fields, i.e. for the restaurant example, fields for fields.menu and fields.openingHours. You could even limit the entries a link field can point to by specifying link content type validation on the field.
  • array of links field, i.e. fields.menuItems in the restaurant’s menu, representing an ordered list of related items.

 

Example – modeling a product catalogue
One of the template spaces in Contentful is for a product catalogue, consists of:

A Category: What product type is it?
A Brand: Who made the product?
A Product: An item for sale that references a category and a brand.

Brand content type consists of the following fields:

Company Name: A text field represents the title of the entry, it’s required, with the Single line appearance setting
Logo: A media field that references assets
Description: Describes the brand, longer text field with Markdown editor enabled
Website, Twitter, Email: contact details for the brand. They have validation rules to ensure the correct contact information
Phone #: Another text field, but one that allows a user to add a list of values

 

ref : https://www.contentful.com/developers/docs/concepts/data-model/

[ contentful ] Exploring the Contentful API from the docs

Get all entries of a Space

entries_collection

ref : https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/entries/entries-collection/get-all-entries-of-a-space/console/js

Selected space

/spaces/yadj1kx9rmg0/environments/{environment_id}/entries?access_token=fdb4e7a3102747a02ea69ebac5e282b9e44d28fb340f778a4f5e788625a61abe&content_type=2PqfXUJwE8qSYKuM0U6w8M&select=fields.productName

ref : https://www.contentful.com/developers/docs/references/content-delivery-api/#/reference/search-parameters/select-operator/query-entries/console/js

query_entries_api

 

&access_token=whatever

&content_type=contentTypeId

&select=fields.productName, fields.name, fields.website, sys.id, sys.updatedAt    // select `productName`, `sys.id`, `sys.updatedAt` fields

 

Test call response button.

 

contentTypeId.png

 

Example Response

{
sys: {
type: 'Array'
},
total: 4,
skip: 0,
limit: 100,
items: [
{
fields: {
productName: 'SoSo Wall Clock'
},
sys: {
id: 'whatever',
updatedAt: '2017-02-21T14:29:672Z'
}
},
{
fields: {
productName: 'Whisk Booter'
},
sys: {
id: 'whatever',
updatedAt: '2017-02-21T14:29:672Z'
}
},
]
}

 

pongTestAPIKey.png

 

ref : https://www.contentful.com/developers/docs,

https://www.contentful.com/developers/bits-and-bytes/#exploring-the-contentful-api-from-the-docs

[ contentful ] preview and testing environment

/entries

request URL : https://cdn.contentful.com/…

 

contentful.js

const contentful = require('contentful') // 66.2K (gzipped: 21K)

const defaultConfig = {

CTF_SPACE_ID: process.env.CTF_SPACE_ID,

CTF_CDA_TOKEN: process.env.CTF_CDA_TOKEN,

CTF_CPA_TOKEN: process.env.CTF_CPA_TOKEN

}

module.exports = {

createClient (config = defaultConfig){

// preview environment

// using the Content Preview API

const options = {

host: 'preview.contentful.com', // that use CPA

space: config.CTF_SPACE_ID,

accessToken: config.CTF_CPA_TOKEN

}

// production environment

// using the Content Delivery API

if (process.env.NODE_ENV === 'production') { // check if production environment

options.host = 'cdn.contentful.com' // by reaching cdn, NOTE : options.host = 'cdn.contentful.com' ( default )

options.accessToken = config.CTF_CDA_TOKEN

}

return contentful.createClient(options) // create contentful client

}

}

 

Adding Content Preview

select post ContentType

adding_content_preview.png

Testing : Preview when writing content

new_preview_button_when_writing_content.png

 

ref : https://www.contentful.com/developers/bits-and-bytes/#creating-a-preview-environment-using-the-preview-api

 

[ contentful ] Ship little data with images API

${entry.fields.headerImage.fields.file.url}
  • Change format
  • JPEG quality
  • Progressive JPEGs
  • Resizing & Cropping

References

crop_and_resize.png

&w=NNN&h=NNN

${entry.fields.headerImage.fields.file.url}?w=820&h=250

keep the aspect ratio ( h=250 ), but the w is not correct

&fit=fill

${entry.fields.headerImage.fields.file.url}?w=820&h=250&fit=fill

took the center of images, and cut the rest

&f=top : focus area will be top

${entry.fields.headerImage.fields.file.url}?w=820&h=250&fit=fill&f=top

&fm=jpg

jpg, png or webp

png small than jpg

Not cross support : webp

 

picture

source srcset="${entry.fields.headerImage.fields.file.url}?w=820&h=250&fit=fill&fm=webp" type="image/webp"

img src="${entry.fields.headerImage.fields.file.url}?w=820&h=250&fit=fill"

/picture

For browser that is not support webp, will fallback to the img element.

 

ref : https://www.contentful.com/developers/bits-and-bytes/#how-to-save-bytes-on-the-wire-using-the-images-api

ref : https://www.contentful.com/developers/docs/references/images-api/

[ contentful ] CDA : content delivery API : cdn.contentful.com

read-only API for delivering content from Contentful to apps, websites and other media. Content is delivered as JSON data, and images, videos and other media as files.

The API is available via a globally distributed content delivery network (CDN).

 

Authentication ( specific to particular environment )

You have two options to supply the access token, either as an Authorization request header field, or as an access_token URI query parameter. The CDA implements the standardized OAuth 2.0 bearer token specification already supported by many HTTP clients.

  • OAuth tokens – Use if you’re building a public integration that requests access to other Contentful user’s data

Contentful doesn’t have an API for acquiring an OAuth token directly for a user account, OAuth 2.0 applications ( following this to create OAuth 2.0 applications https://www.contentful.com/developers/docs/extensibility/oauth/ ) acquire them.

 

To Read : https://www.contentful.com/developers/docs/references/content-delivery-api/#/introduction/api-rate-limits

 

ref : https://www.contentful.com/developers/docs/references/content-delivery-api/

[ contentful ] CMA : content management API : api.contentful.com

“GET” responses retrieve the entirety of items (i.e. all localized and unpublished content).

  • Personal access tokens – Use if you’re using the content management API to access data from your own Contentful user account

api_token.png

Resource IDs
Let the API generate a random ID for you /or can specify an ID. If you choose an ID yourself it must adhere to the following rules:

  • length between 1 and 64 characters
  • only includes alphanumeric characters, dots ., hyphens – or underscores _

Represented as a regular expression, this is /^[a-zA-Z0-9\.-_]{1,64}$/

Updating content
Contentful doesn’t merge changes made to content, so when updating content, you need to send the entire body of an entry. If you update content with a subset of properties, you will lose all existing properties not included in that update.

You should always update resources in the following order:

  • Fetch current resource
  • Make changes
  • Update the resource by passing changed resource along with current version number

This way no unseen changes are overridden and unexpected conflicts are unlikely to occur.

Note: You can’t update any of the sys property fields, including sys.id.

Updating and version locking
Contentful uses optimistic locking. When updating an existing resource, you need to specify its current version with the X-Contentful-VersionHTTP header (this header is automatically set when using our official SDKs). Contentful compares this version with the current version stored to ensure that a client doesn’t overwrite a resource that has since been updated. If the version changed in-between, Contentful would reject the update.

Rate limits

rate limits of 10 requests/second and 36000 requests/hour. Higher rate limits may apply depending on your current plan.

429 Too Many Requests HTTP status code and return rate limiting headers

X-Contentful-RateLimit-Hour-Limit: 36000 // maximum amount of requests/hour
X-Contentful-RateLimit-Hour-Remaining: 35891 // remaining amount of requests which can be made until the next hourly reset
X-Contentful-RateLimit-Reset: 0 // maximum amount of requests/second. if > 0, specifying the time before one of the two limits resets and another request will be accepted

// If the client is rate limited/second, return 1, means the next second.

// If the client is rate limited/hour, every request which was made in the last hour gets counted in one of four 15 minute buckets.
X-Contentful-RateLimit-Second-Limit: 10 // remaining amount of requests which can be made until the next secondly reset
X-Contentful-RateLimit-Second-Remaining: 9 // number of seconds until the next request can be made

TODO : read https://www.contentful.com/developers/docs/references/content-management-api/#/introduction/api-rate-limits

Common Resource Attributes

{
"sys": {
"type": "Space",
"id": "yadj1kx9rmg0"
}
}

sys.id: is defined for every resource that is not a collection

  • is either automatically generated ( spaces id ) or
  • specified in the URL (e.g. entries/entryId) of initial PUTrequest

REF : https://www.contentful.com/developers/docs/references/content-management-api/#/introduction/common-resource-attributes

Collection resources and pagination

{
"sys": { "type": "Array" },
"skip": 0,
"limit": 100,
"total": 1256,
"items": [ /* 100 individual resources */ ]
}

“skip”: 100 // offset

“order”: “sys.createdAt”

API versioning header

Content-Type: application/vnd.contentful.management.v1+json

If not specified, Contentful will route your request to the latest version of the API. To be certain, always specify the Content-Type header.

Modeling guide : https://www.contentful.com/developers/docs/concepts/data-model/

 

Example : delete entry

Install contentful

npm install contentful

 

var contentful = require('contentful')

const contentfulManagement = require('contentful-management')

const contentfulCDAClient = contentful.createClient({
space: CONTENTFUL_SPACE_ID,
accessToken: CONTENTFUL_CDA_ACCESS_TOKEN,
})

const contentfulCMAClient = contentfulManagement.createClient({
accessToken: CONTENTFUL_CMA_ACCESS_TOKEN,
})

const space = await contentfulCMAClient.getSpace(spaceId)
const client = await space.getEnvironment(env)
const entry = await client.getEntry(contentfulId)

// require un-publish before delete
const unPublishedEntry = await entry.unpublish()
// deletedEntry return undefined after entry deleted
// eslint-disable-next-line no-unused-vars
const deletedEntry = await unPublishedEntry.delete()

 

ref : https://www.contentful.com/developers/docs/references/content-management-api/,

https://contentful.github.io/contentful-management.js/contentful-management/5.3.5/ContentfulClientAPI.html

[ Contentful ] headless CMS

contentful-cli

use Content Management API

 

Installation

npm i -g contentful-cli

Testing 

which contentful

USAGE

contentful CMD ARGS

CMD

* boilerplate : download boilerplate

* guide

* login

* logout

* space : create new space

login

contentful login

get authorize token to manage content in all spaces and paste to CLI

The token will be stored in /Users/whatever/.contentfulrc.json

list all spaces

contentful use

then select space

select space

contentful --space-id spaceId

boilerplate

contentful boilerplate

Choose > Contentful Javascript Boilerplate

then the program create CDA access token, download contentful javascript boilerplate, write files to disk

Downloading contentful to /Users/whatever/boilerplate-javascript.zip

 

unzip boilerplate-javascript.zip -d boilerplate-javascript
npm install

index.js

...

function runBoilerplate () {
  displayContentTypes()
  .then(displayEntries)

  ...

}

...

function displayContentTypes () {

   return fetchContentTypes()

   ...

}

function displayEntries (contentTypes) {

   ...

}

function fetchContentTypes () {
  return client.getContentTypes() // fetch contentTypes

  ...

}

function fetchEntriesForContentType (contentType) {
  return client.getEntries({                           // fetch certain contentType
    content_type: contentType.sys.id
  })

  ...

}

runBoilerplate()

start boilerplate

npm start

Fetching and displaying content type

id | title | fields

Post | 

Talk | 

Event | 

Fetching and displaying entries

Content Type Post:

Id | Title

XXX | XXX

Content Type Talk:

Id | Title

5NFOskY480eKksk0Cyayak | The hidden cost of performance marketing

Content Type Event:

Id | Title

YYY | YYY

 

Documentation : https://www.contentful.com/developers/docs/javascript/tutorials/using-js-cda-sdk/

 

A guide introducing basic concepts of working with Contentful

contentful guide

Which space name : Get Started Guide

contentful space create --name 'Get Started Guide'

Create Your space now ? Y

Successfully created space Get Started Guide (vjtxsen84nyf)

Populate the Content model to your Space now ? Y

Fetching release information of contentful/content-models

Download latest release information of contentful/content-models

Unpacking latest release of contentful/content-models

import Finished importing all data

The following entities were imported

| Content Types | 2 |

| Editor Interfaces | 2 |

| Entries | 4 | // import 4 entries

| Assets | 4 | // import 4 assets

| Locales | 1 |

| Webhooks | 0 |

| Roles | 7 |

The content model was applied to Get Started Guide (vjtxsen84nyf) space

The source code of the Custom app will be stored at:

/Users/whatever/contentful-custom-app

> Fetching release information of contentful/blog-in-5-minutes

> Downloading latest release of contentful/blog-in-5-minutes

> Unpacking latest release of contentful/blog-in-5-minutes

 

Installing dependencies

> Test if yarn is available

> Install via npm

> Generate custom delivery access token with the name ‘Contentful Get Started Guide’

> Setting up project configuration files

 

Run Custom app locally in development mode now ? Y

npm run dev

NUXT JS ( https://nuxtjs.org or https://github.com/nuxt/nuxt.js ) build on top of vueJS : static HTML generater + javascript

 

article section / article view

CMS is at contentful.com

Example : change the title of “Hello World” post

 

ref: https://www.contentful.com/developers/bits-and-bytes/?wvideo=adbzmfz24u&utm_campaign=new-org-activate&utm_medium=email&utm_source=intercom&utm_content=contentful-in-a-nutshell-a&utm_term=#a-web-project-in-5-minutes-using-the-contentful-cli

 

Create Access Token

APIs > Content management tokens > Personal Access Tokens

Generate Personal Access Token

Token Name : __

Token : CFPAT-…..

copy the token right now, or never see that again

 

revoke token

 

Postman

GET https://api.contentful.com/spaces/

Authorization: Bearer CFPAT-…..

Accept: application/vnd.contentful.management.v1+json

 

 

http://app.contentful.com > content model

 

contentful-import : https://github.com/contentful/contentful-import

contentful-export : https://github.com/contentful/contentful-export

 

ref : https://www.contentful.com/developers/bits-and-bytes/?wvideo=adbzmfz24u&utm_campaign=new-org-activate&utm_medium=email&utm_source=intercom&utm_content=contentful-in-a-nutshell-a&utm_term=#how-to-get-started-with-the-contentful-cli

twitter : @stafanjudis

 

Getting started

next : https://www.contentful.com/developers/docs/tutorials/general/get-started/