Action

Create Multiple Trello Cards (API)

Posted by enivrezvous, Last update 5 days ago

This Drafts action creates Trello cards in the background using Trello’s REST API. Each non-empty line in your draft becomes a Trello card.

FORMAT PER LINE

Use this format for each card:

Title :: Description

The part before “::” is the card title.

The part after “::” is the description (optional).

Regardless of whether you include a description or not, the action appends a standard template:

Why →
Blockers →
Done →
Next →

This ensures all cards follow the same structure.

REQUIRED SETUP (ONE-TIME)

Before the script can create cards, it needs three pieces of Trello information:

  1. API Key
  2. API Token
  3. List ID (the specific list where new cards should be created)

Drafts will prompt you for these the first time you run the action, and will store them securely.

HOW TO GET YOUR TRELLO API KEY

Trello now requires an API key to come from a private Power-Up. You do not need to build anything — just create a placeholder.

  1. Open this page in a browser:

    https://trello.com/power-ups/admin

  2. Click “New”, create a Power-Up, and use any placeholder URL (e.g., https://example.com).

    This Power-Up will never be used; it only unlocks API access.

  3. Open the Power-Up you created and go to the API Key section.

  4. Click Generate API Key and copy it.

HOW TO GET YOUR TRELLO API TOKEN

On the same API Key page:

  1. Next to your API key, click the Token link.
  2. Trello will ask for permission — choose Allow.
  3. Copy the long token string that appears.

HOW TO GET YOUR BOARD ID

You may sometimes need your board’s internal ID. Trello uses two identifiers:

• Shortlink (the short code in the URL, e.g. 89H1nfOm)

• Board ID (a long internal ID used by the API)

To find the board ID:

  1. Open your Trello board in a browser.
  2. Look at the URL and note the shortlink, for example:
    https://trello.com/b/91F1ncRm/your-board-name
  3. Open this URL in your browser (replace SHORTLINK, KEY and TOKEN):

https://api.trello.com/1/boards/SHORTLINK?key=KEY&token=TOKEN

  1. The response will be JSON. Look for the "id" field near the top.
    That value is your board’s internal ID.

The script does not need the board ID directly, but it can be useful when exploring the API or troubleshooting.

HOW TO GET YOUR LIST ID (idList)

The script needs the ID of the list where new cards will be created.

  1. Open this URL in your browser (replace SHORTLINK, KEY and TOKEN):

https://api.trello.com/1/boards/SHORTLINK/lists?key=KEY&token=TOKEN

  1. Find the list you want to target (e.g. “Incoming”).
  2. Copy its “id” field.
    That value is the idList you will paste into Drafts.

EXAMPLE OF A LIST OBJECT

{
“id”: “54f95f1r10c39aj2yay99832”,
“name”: “Incoming”,

}

In this example, you would use:

54f95f1r10c39aj2yay99832

ONGOING USE

Once you enter your API key, token, and list ID, Drafts remembers them.

Running the action later will instantly create all cards in the chosen Trello list — with no app switching and no Trello UI opening.

To change the list later:

Run the action → tap “Edit Credentials” → update the List ID.

Steps

  • script (iOS only)

    // Drafts → Trello (REST API, no app switching)
    // - One card per non-empty line
    // - Line format: "Title :: Description"
    // - Appends a template to the description
    // - Uses Trello API key, token, and list ID stored in a Drafts Credential
    
    // ===== Settings (logic only) =====
    const DELIM = "::";
    const ALWAYS_APPEND_TEMPLATE = true;
    const APPEND_TEMPLATE_WHEN_NO_DESC = true;
    
    const TEMPLATE =
      "Why → \n" +
      "Blockers → \n" +
      "Done → \n" +
      "Next → ";
    
    // ===== Helper: build description =====
    function buildDescription(userDesc) {
      const trimmed = (userDesc || "").trim();
    
      // No description supplied
      if (!trimmed) {
        return APPEND_TEMPLATE_WHEN_NO_DESC ? TEMPLATE : "";
      }
    
      // Description supplied
      if (ALWAYS_APPEND_TEMPLATE) {
        return trimmed + "\n\n" + TEMPLATE;
      } else {
        return trimmed;
      }
    }
    
    // ===== Trello credentials (stored securely in Drafts) =====
    // This will prompt once for key, token, and listId (“Incoming”), then reuse them.
    let cred = Credential.create(
      "TrelloAPI",
      "Enter your Trello API key, token, and target list ID (idList) for Incoming."
    );
    cred.addTextField("key", "API Key");
    cred.addPasswordField("token", "API Token");
    cred.addTextField("listId", "List ID (Incoming)");
    
    if (!cred.authorize()) {
      context.cancel("Trello authorization cancelled.");
      throw new Error("Authorization cancelled.");
    }
    
    const apiKey = cred.getValue("key");
    const token = cred.getValue("token");
    const TRELLO_LIST_ID = cred.getValue("listId"); // e.g. 65b96f1d09c09af2faf99732
    
    // ===== Main: process lines and create cards via REST API =====
    const lines = draft.content
      .split("\n")
      .map(l => l.trim())
      .filter(l => l.length > 0);
    
    let http = HTTP.create();
    let failures = [];
    
    for (let line of lines) {
      // Default: whole line is the card name
      let name = line;
      let description = "";
    
      // Split "Title :: Description"
      const idx = line.indexOf(DELIM);
      if (idx !== -1) {
        name = line.substring(0, idx).trim();
        description = line.substring(idx + DELIM.length).trim();
      }
    
      // Build final description with template logic
      const finalDesc = buildDescription(description);
    
      // Skip if name somehow ends up empty
      if (!name) {
        console.log("Skipped line with empty name: " + line);
        continue;
      }
    
      // Create card via Trello REST API
      let response = http.request({
        url: "https://api.trello.com/1/cards",
        method: "POST",
        timeout: 20,
        data: {
          key: apiKey,
          token: token,
          idList: TRELLO_LIST_ID,
          name: name,
          desc: finalDesc
        }
      });
    
      if (
        !response.success ||
        (response.statusCode !== 200 && response.statusCode !== 201)
      ) {
        console.log(
          "Failed to create card for line: " +
            name +
            " | Status: " +
            response.statusCode +
            " | Body: " +
            response.responseText
        );
        failures.push(name);
      } else {
        try {
          let card = JSON.parse(response.responseText);
          console.log("Created card: " + card.name + " (" + card.shortUrl + ")");
        } catch (e) {
          console.log("Created card (JSON parse failed, but status OK): " + name);
        }
      }
    }
    
    if (failures.length > 0) {
      context.fail("Failed to create cards for: " + failures.join(", "));
    } else {
      // Everything succeeded – cards created in Incoming, no app switching
      // You can uncomment the next line if you want Drafts to explicitly mark success:
      // context.succeed();
    }
  • prompt (macOS only)

    promptKey
    prompt
    promptTitle
    Prompt
    promptMessage
    This action is available only on iOS, due to differences between the iOS and Mac version of Fantastical.
    promptButtons
    OK
    includeTextField
    false
    textFieldDefault
    includeCancelButton
    false

Options

  • After Success Trash
    Notification Info
    Log Level Info
Items available in the Drafts Directory are uploaded by community members. Use appropriate caution reviewing downloaded items before use.