Quick-search for anything
⌘F

Developer Migration Docs

If no export tools exist for your current blogging system you’ll need to create one that generates a JSON file as described here. There is a full example at the end of this file. Please note that your final JSON file should have no comments in the final format. Those are only included here for readability and explanatory purposes.

JSON file structure

First and foremost, your JSON file must contain valid JSON. You can test your file is valid using the JSONLint online tool.

The file structure can optionally be wrapped in:

{
  "db": [...contents here...]
}

Both with and without are valid Ghost JSON files. But you must include a meta and a data object.

The meta object

"meta": {
    "exported_on":1408552443891,
    "version":"2.14.0"
}

The meta block expects two keys, exported_on and version. exported_on should be an epoch timestamp in milliseconds, version should be the Ghost version the import is valid for.

The data block

Ghost’s JSON format mirrors the underlying database structure, rather than the API, as it allows you to override fields that the API would ignore.

"data": {
  "posts": [{...}, ...],
  "tags": [],
  "users": [],
  "posts_tags": [],
  "posts_authors": [],
  "roles_users": []
}

The data block contains all of the individual post, tag, and user resources that you want to import into your site, as well as the relationships between all of these resources. Each item that you include should be an array of objects.

Relationships can be defined between posts and tags, posts and users (authors) and between users and their roles.

IDs inside the file are relative to the file only, so if you have a post with id: 1 and a posts_tags object which references post_id: 1, then those two things will be linked, but they do not relate to the post with id: 1 in your database.

Example

{
    "meta":{
        // epoch time in milliseconds
        "exported_on":  1388805572000,
        "version":      "2.14.0"
    },
    "data":{
        "posts": [
            {
                "id": 1,
                "title":         "my blog post title",
                "slug":          "my-blog-post-title", // Optional, will be generated by Ghost if missing
                // Lexical is used to represent your content
                "lexical":       "{\"root\":{\"children\":[{\"children\":[{\"detail\":0,\"format\":0,\"mode\":\"normal\",\"style\":\"\",\"text\":\"Hello, beautiful world! 👋\",\"type\":\"extended-text\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"paragraph\",\"version\":1}],\"direction\":\"ltr\",\"format\":\"\",\"indent\":0,\"type\":\"root\",\"version\":1}}",
                "feature_image": null,
                "feature_image_alt": null,
                "feature_image_caption": null,
                "featured":      0, // boolean indicating featured status
                "page":          0, // boolean indicating if this is a page or post
                "status":        "published", // or draft
                "published_at":  1283780649000, // epoch time in milliseconds
                "published_by":  1, // the first user created has an id of 1
                "meta_title":    null,
                "meta_description":null,
                "email_only":    false, // boolean indicating email-only type of post
                "author_id":     1, // the first user created has an id of 1
                "created_at":    1283780649000, // epoch time in milliseconds
                "created_by":    1, // the first user created has an id of 1
                "updated_at":    1286958624000, // epoch time in milliseconds
                "updated_by":    1 // the first user created has an id of 1
            }
        ],
        "tags": [
            {
                "id":           5,
                "name":         "Colorado Ho!",
                "slug":         "colorado-ho", // Optional, will be generated by Ghost if missing
                "description":  ""
            }
        ],
        "posts_tags": [
            {"tag_id": 5, "post_id": 1},
        ],
        "users": [
            {
                "id":           3,
                "name":         "Jo Bloggs",
                "slug":         "jo-blogs", // Optional, will be generated by Ghost if missing
                "email":        "jo@example.com",
                "profile_image": null,
                "cover_image":   null,
                "bio":           null,
                "website":       null,
                "location":      null,
                "accessibility": null,
                "meta_title":    null,
                "meta_description": null,
                "created_at":    1283780649000, // epoch time in millis
                "created_by":    1,
                "updated_at":    1286958624000, // epoch time in millis
                "updated_by":    1
            }
        ],
        // Provide this if you want different roles to the default "Author" role
        "roles_users": [
            {
                "user_id": 2,
                "role_id": ObjectId // This must reference the id from your database
            }
        ]
    }
}