{
  "$schema": "http://json-schema.org/draft-07/schema#",
  "$id": "https://getshiori.app/schemas/import/v1",
  "title": "Shiori import",
  "description": "The shiori_import document: the import file for POST /v1/imports and the full JSON export (SOLUTION_DESIGN.md 10.1, 11.1). Dates are { on, precision } pairs; on is null exactly when precision is unknown.",
  "type": "object",
  "properties": {
    "format": {
      "type": "string",
      "const": "shiori_import"
    },
    "version": {
      "type": "number",
      "const": 1
    },
    "exported_at": {
      "type": "string",
      "format": "date-time"
    },
    "timezone": {
      "type": "string"
    },
    "entries": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/ImportEntry"
      },
      "maxItems": 50000
    },
    "deleted_entries": {
      "type": "array",
      "items": {
        "$ref": "#/definitions/DeletedEntry"
      },
      "maxItems": 50000,
      "default": []
    }
  },
  "required": [
    "format",
    "version",
    "entries"
  ],
  "additionalProperties": true,
  "definitions": {
    "ImportEntry": {
      "type": "object",
      "properties": {
        "client_ref": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "item": {
          "$ref": "#/definitions/ImportItemRef"
        },
        "status": {
          "type": "string",
          "enum": [
            "planned",
            "in_progress",
            "finished",
            "paused",
            "dropped"
          ]
        },
        "started": {
          "type": "object",
          "properties": {
            "on": {
              "anyOf": [
                {
                  "type": "string",
                  "pattern": "^\\d{4}-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$",
                  "description": "Calendar date as YYYY-MM-DD, no time component"
                },
                {
                  "type": "null"
                }
              ],
              "description": "Calendar date as YYYY-MM-DD, no time component",
              "default": null
            },
            "precision": {
              "type": "string",
              "enum": [
                "day",
                "month",
                "year",
                "unknown"
              ],
              "description": "How much of the calendar date is known"
            }
          },
          "required": [
            "precision"
          ],
          "additionalProperties": false,
          "description": "A calendar date with its precision; { on: null, precision: unknown } when not known",
          "default": {
            "on": null,
            "precision": "unknown"
          }
        },
        "finished": {
          "$ref": "#/definitions/ImportEntry/properties/started",
          "default": {
            "on": null,
            "precision": "unknown"
          },
          "description": "A calendar date with its precision; { on: null, precision: unknown } when not known"
        },
        "rating": {
          "anyOf": [
            {
              "type": "integer",
              "minimum": 1,
              "maximum": 10
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "repeat_index": {
          "type": "integer",
          "minimum": 1,
          "maximum": 1000,
          "default": 1
        },
        "progress": {
          "anyOf": [
            {
              "type": "integer",
              "minimum": 0,
              "maximum": 1000000
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "review": {
          "anyOf": [
            {
              "type": "string",
              "maxLength": 20000
            },
            {
              "type": "null"
            }
          ],
          "default": null
        },
        "review_visibility": {
          "type": "string",
          "enum": [
            "private",
            "unlisted",
            "public"
          ],
          "default": "private"
        },
        "hidden": {
          "type": "boolean",
          "default": false
        },
        "links": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "rel": {
                "type": "string",
                "enum": [
                  "review",
                  "post",
                  "other"
                ]
              },
              "url": {
                "type": "string",
                "format": "uri",
                "maxLength": 2048
              }
            },
            "required": [
              "rel",
              "url"
            ],
            "additionalProperties": false
          },
          "maxItems": 20,
          "default": []
        },
        "source": {
          "type": "string",
          "enum": [
            "manual",
            "mal",
            "steam",
            "xbox",
            "psn",
            "trakt",
            "letterboxd_rss",
            "letterboxd_csv",
            "goodreads_csv",
            "goodreads_rss",
            "plex",
            "jellyfin",
            "shiori_import"
          ],
          "default": "shiori_import"
        },
        "source_ref": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "locked_fields": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": [
              "status",
              "started",
              "finished",
              "rating",
              "progress",
              "review",
              "review_visibility",
              "hidden",
              "edition_id"
            ]
          },
          "default": []
        },
        "field_sources": {
          "type": "object",
          "additionalProperties": {
            "$ref": "#/definitions/ImportEntry/properties/source"
          },
          "default": {}
        },
        "secondary_sources": {
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "source": {
                "$ref": "#/definitions/ImportEntry/properties/source"
              },
              "source_ref": {
                "type": "string",
                "minLength": 1,
                "maxLength": 200
              },
              "seen_at": {
                "type": "string"
              }
            },
            "required": [
              "source",
              "source_ref",
              "seen_at"
            ],
            "additionalProperties": false
          },
          "maxItems": 20,
          "default": []
        }
      },
      "required": [
        "item",
        "status"
      ],
      "additionalProperties": false
    },
    "ImportItemRef": {
      "type": "object",
      "properties": {
        "media_type": {
          "type": "string",
          "enum": [
            "movie",
            "tv",
            "anime",
            "manga",
            "book",
            "game"
          ]
        },
        "title": {
          "type": "string",
          "minLength": 1,
          "maxLength": 500
        },
        "title_english": {
          "type": "string",
          "maxLength": 500
        },
        "year": {
          "type": "integer",
          "minimum": 1800,
          "maximum": 2200
        },
        "season": {
          "type": "integer",
          "minimum": 0,
          "maximum": 500
        },
        "show_title": {
          "type": "string",
          "maxLength": 500
        },
        "ids": {
          "type": "object",
          "additionalProperties": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200
          },
          "propertyNames": {
            "enum": [
              "tmdb_movie",
              "tmdb_tv",
              "tmdb_season",
              "imdb",
              "tvdb_series",
              "trakt",
              "letterboxd",
              "wikidata",
              "mal_anime",
              "mal_manga",
              "anilist",
              "anidb",
              "kitsu",
              "simkl",
              "ol_work",
              "ol_edition",
              "isbn13",
              "goodreads_book",
              "goodreads_work",
              "google_books",
              "hardcover",
              "igdb",
              "steam_app",
              "xbox_title",
              "psn_title",
              "gog",
              "epic",
              "rawg"
            ]
          },
          "default": {}
        },
        "author": {
          "type": "string",
          "maxLength": 500
        },
        "isbn13": {
          "type": "string",
          "pattern": "^97[89]\\d{10}$"
        }
      },
      "required": [
        "media_type",
        "title"
      ],
      "additionalProperties": false
    },
    "DeletedEntry": {
      "type": "object",
      "properties": {
        "source": {
          "$ref": "#/definitions/ImportEntry/properties/source"
        },
        "source_ref": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "repeat_index": {
          "type": "integer",
          "minimum": 1,
          "default": 1
        },
        "deleted_at": {
          "type": "string"
        },
        "item": {
          "$ref": "#/definitions/ImportItemRef"
        }
      },
      "required": [
        "source",
        "source_ref"
      ],
      "additionalProperties": false
    }
  }
}
