Skip to content

Components and media ​

A component (ComponentState) is one printed part of a job: the cover, the text block, an insert. Each component belongs to one job (jobId) and carries its own quantity, print specification and artwork files. Operations and milestones can point at a component through componentId (see Job management).

Component kinds ​

kind is a ComponentKind:

ValueUse for
COVERCovers
TEXT, CONTENT, MAINText block or main body
INSERT, OUTSERTInserted or attached pieces
ENDPAPEREndpapers of a case-bound book
DUST_JACKETDust jackets
OTHERAnything else

Add a component ​

jobId, name, kind and quantity are required.

graphql
mutation AddCover {
  createComponent(
    input: {
      jobId: "job_01M0R249JMETNBM1Z7466MXGZD"
      name: "Cover"
      kind: COVER
      quantity: 5000
      externalId: "MIS-2026-0042-COVER"
      sortOrder: 1
    }
  ) {
    component {
      id
    }
    errors {
      path
      message
    }
  }
}

createComponent rejects an externalId that another component already uses.

The print specification (page count, colours, layout, media, finished size, finishing) is set through upsertComponent, which takes the same required fields plus the specification fields of UpsertComponentInput. For example, to set the page count:

graphql
mutation SetPageCount {
  upsertComponent(
    input: {
      id: "cmp_01M0R249NQEQGR8E91ZHP09KP0"
      jobId: "job_01M0R249JMETNBM1Z7466MXGZD"
      name: "Text block"
      kind: TEXT
      quantity: 5000
      totalPages: 48
    }
  ) {
    component {
      id
      totalPages
    }
    errors {
      path
      message
    }
  }
}

Specification fields you leave out keep their current value; passing null clears one.

Read the print specification ​

graphql
query ComponentSpec {
  getComponent(id: "cmp_01M0R249NQEQGR8E91ZHP09KP0") {
    id
    name
    kind
    quantity
    totalPages
    colors {
      frontColorCount
      backColorCount
      front {
        colors {
          name
          colorType
        }
      }
    }
    layout {
      trimBox {
        width {
          millimeters
        }
        height {
          millimeters
        }
      }
      bleed {
        top {
          millimeters
        }
      }
    }
    media {
      name
      kind
      stockType
      grainDirection
      weight {
        gsm
      }
    }
    desiredSubstrate {
      id
      name
    }
  }
}

The specification objects are optional; a component without them returns null.

Lengths and weights ​

Every dimension is a Length. It keeps the value and unit it was entered with (raw, unit) and gives you conversions, so you never convert units yourself:

graphql
query SubstrateSizes {
  listSubstrates(first: 10, filter: { isActive: { eq: true } }) {
    edges {
      node {
        id
        name
        width {
          raw
          unit
          millimeters
          inches
        }
        thickness {
          value(unit: UM)
        }
        weight {
          gsm
        }
      }
    }
  }
}

LengthUnit values are UM, MM, CM, IN and PT. Paper weight (PaperWeight) is exposed as gsm, or with value(unit:).

Substrates ​

The stock a component is printed on can be a substrate record (SubstrateState) from your material catalogue. A component has a desiredSubstrate (what was specified) and an actualSubstrate (what was used). Substrates carry the full media description: kind (SHEET or ROLL), stockType, grainDirection (ANY, LONG, SHORT), coatings, weight, thickness, size and cost data. Browse them with listSubstrates, filtering on name, externalId, kind, coating or isActive.

Artwork files ​

A component's files are linked through ComponentArtworkFileState. Each link points either at a file stored in CoCoCo (fileId) or at an external URL (externalUri), and has a usageRole (ComponentFileUsageRole): ARTWORK, TEMPLATE, DATA, PATH or OTHER.

Link an external PDF:

graphql
mutation AttachArtwork {
  upsertComponentArtworkFile(
    input: {
      componentId: "cmp_01M0R249NQEQGR8E91ZHP09KP0"
      externalUri: "https://<your-file-host>/jobs/0042/text.pdf"
      usageRole: ARTWORK
      pageRange: "1-48"
      description: "Text block, print-ready"
    }
  ) {
    artworkFile {
      id
      usageRole
    }
    errors {
      path
      message
    }
  }
}

List a component's files:

graphql
query ComponentFiles {
  listComponentArtworkFiles(componentId: "cmp_01M0R249NQEQGR8E91ZHP09KP0") {
    id
    usageRole
    pageRange
    externalUri
    file {
      id
      name
      mimeType
      status
    }
  }
}

Pass id to upsertComponentArtworkFile to change an existing link, and use deleteComponentArtworkFile to remove one.

Uploading files to CoCoCo ​

To store a file in CoCoCo itself (FileState), upload it in three steps:

  1. Call requestFileUploads with the file's name, MIME type, size and FileCategory. You can link it to a job or component in the same call. Each grant returns a fileId and a pre-signed uploadUrl.
  2. Upload the bytes to uploadUrl before it expires.
  3. Call completeFileUploads with the fileId. CoCoCo checks that the bytes arrived and marks the file READY.

Uploads need file storage to be set up for your tenant; if it is not, the errors list says so.

graphql
mutation RequestUpload {
  requestFileUploads(
    inputs: [
      {
        componentId: "cmp_01M0R249NQEQGR8E91ZHP09KP0"
        name: "Text block"
        originalFilename: "text.pdf"
        mimeType: "application/pdf"
        sizeBytes: 18234567
        category: ARTWORK
        usageRole: ARTWORK
      }
    ]
  ) {
    grants {
      fileId
      uploadUrl
      expiresAt
    }
    errors {
      path
      message
    }
  }
}
graphql
mutation CompleteUpload {
  completeFileUploads(inputs: [{ fileId: "fil_01M0R24D3F7K9P2W5X8Z1B4N6Q" }]) {
    files {
      id
      status
    }
    errors {
      path
      message
    }
  }
}

Then link the file to the component with upsertComponentArtworkFile and its fileId. To download a stored file, fileDownloadUrl(id:) returns a short-lived URL.

Listing components ​

graphql
query JobComponents {
  listComponents(
    filter: { jobId: { eq: "job_01M0R249JMETNBM1Z7466MXGZD" } }
    sort: [{ field: SORT_ORDER, direction: ASC }]
  ) {
    edges {
      node {
        id
        name
        kind
        quantity
      }
    }
  }
}

ComponentFilterInput filters on jobId, name, kind (as a string, for example kind: { eq: "COVER" }) and externalId. For one job, getJob { components { … } } returns the same records without paging.

Good practice ​

  • Give every file link a clear usageRole, so that print files, templates and variable data are not confused.

Connect machines, automate workflows, and build custom apps for print production.