Nubu
  • Features
  • How it works
  • Pricing
  • Integrations
  • FAQ
  • Contact
  • Docs
  • Blog
  • Log in
  • Log inSign up
    Nubu

    Creative automation for teams that ship campaigns, not busywork.

    Try for free
    Product
    FeaturesNubu MotionHow it worksPricingIntegrationsFAQ
    Company
    AboutContactDocsBlogLog in
    Legal
    Privacy policyTerms of serviceData deletion
    © 2026 Bear Studios · Nubu
    Introduction
    Templates overviewInstalling Nubu BuilderAdding template compsAdding propertiesAdding footageSetting defaultsExporting your templateUploading a template
    Flows overviewAvailable nodesAdding a nodeConnecting nodesWorking with dataTemplates and outputsUsing AI nodesBuilding a creative
    CampaignsTemplatesAssetsGlossariesRendersSettings
    Connecting Meta AdsConnecting Google AdsConnecting OpenAIConnecting Gemini AI StudioConnecting Anthropic
    AI Assistant overviewPrompt examplesAssistant settings and controls
    Nubu Motion scripts: the reference
    OverviewQuick startDifferences from After EffectsDeterminism
    JavaScript supportReferences and idsProject scriptsState and timeBudgets and errorsFormatting values
    GlobalTime conversionInterpolationVector mathsRandom and noiseColour conversionOther maths
    LayerCompPropertyKeyframePathGeometryProjectComponentConsoleComponentControlExpressionControl
    The property vocabularyAnimators propertiesAudio propertiesContent propertiesContents propertiesEffects propertiesExpression controls propertiesFills propertiesInstance controls propertiesLayer propertiesLayout propertiesMasks propertiesStrokes propertiesText style propertiesRig propertiesRigging propertiesRig controllers propertiesRigging weights propertiesRigging mesh propertiesRig items propertiesRig splines propertiesRig simulation propertiesRig properties propertiesRig drivers propertiesRig draw order propertiesTransform propertiesTrim path properties
    Error codesBudgets
    Changelog
    API overviewAuthentication and keysRate limits and errorsUploading assetsFoldersUploading templatesTriggering a flowRuns and creativesAPI Request deliveryCallbacks
    All docs
    API

    Uploading templates

    Upload the Nubu Builder's template package as a zip and let Nubu read it.

    A template arrives through the API as the package the Nubu Builder exports: one .zip. Nubu reads it after the upload and checks it exactly as the upload drawer in the app would.

    What the package must contain#

    • the .nubu.json schema and the After Effects .aep project the Builder exported;
    • a thumbnail.jpg or thumbnail.png at the top level;
    • an examples folder with one rendered example per comp, each named after its comp (for example REEL_10S_1080x1920.mp4 or REEL_10S_1080x1920_EXAMPLE.mp4);
    • an After Effects version Nubu supports.

    The Builder's export has all of this. A package that does not is refused with every problem named, and nothing half-finished enters the gallery.

    Uploading#

    The flow is the asset upload's: begin, PUT the zip, complete. A package that would not fit the organisation's remaining storage is refused at the begin, and at a replacement, with 409 conflict and details.reason storage_full; deleting templates frees the space at once.

    curl -X POST https://app.nubu.app/api/v1/templates/uploads \
      -H "Authorization: Bearer nubu_api_..." \
      -H "Content-Type: application/json" \
      -d '{ "filename": "summer-sale.zip", "size_bytes": 83211042, "name": "Summer sale" }'
    

    The answer (201) carries the template_id and an upload plan (a single PUT at or under 100 MiB, else multipart parts; see Uploading assets for the part mechanics, with POST /templates/uploads/<template_id>/parts for fresh part URLs). PUT the zip with Content-Type: application/zip, then complete:

    curl -X POST https://app.nubu.app/api/v1/templates/uploads/<template_id>/complete \
      -H "Authorization: Bearer nubu_api_..." \
      -H "Content-Type: application/json" \
      -d '{}'
    

    (Send { "upload_id": "..." } for a multipart upload.) Nubu reads the package, and the answer carries the ready template: its comps, the examples with the comp each one belongs to, and a download_url for the package.

    A refused package answers 422 validation_failed; details lists one entry per problem, each with a code:

    CodeMeaning
    not_a_zipThe upload is not a zip archive.
    missing_schemaNo .nubu.json in the package.
    missing_aepNo .aep project in the package.
    invalid_schemaThe .nubu.json could not be read.
    missing_version, unsupported_versionThe package declares no After Effects version, or one Nubu does not support.
    no_thumbnailNo thumbnail.jpg or thumbnail.png.
    no_examples, too_many_examplesNo examples, or more than twelve.
    example_unmatchedAn example matches no comp by name (examples names it).
    example_ambiguousTwo examples match the same comp (examples and comp name them).

    Fix the package and upload it again. POST /templates/uploads/<template_id>/abort abandons an upload before it is completed.

    Reading, editing, replacing and deleting#

    • GET /templates lists templates (filters: folder_id, status, q, tag); GET /templates/<id> adds the comps, the examples and a 15-minute download_url for the package.
    • PATCH /templates/<id> with any of name, tags and folder_id.
    • Replacing a package keeps the template id and every flow that uses it. POST /templates/<id>/replace with size_bytes answers an upload plan and a version; PUT the new zip, then POST /templates/<id>/replace/complete with that version (and the upload_id for a multipart one). The new package is checked like a fresh upload; until it passes, the current package stays live. POST /templates/<id>/replace/parts re-mints part URLs and POST /templates/<id>/replace/abort discards the attempt.
    • DELETE /templates/<id> removes the template and its files. A template used by a creative that is queued or rendering answers 409 conflict until that render finishes.