Catalogskills.sh · pipefy

pipefy-attachments

Use this skill when the user wants to upload a file to a Pipefy card or table-record attachment field. Covers local and downloaded file sources, plus a presigned-URL handshake for uploading files directly.

Pending analysisVerified hub608 installs

Savant verdict: Pending analysis

Imported from the source hub; Savant's analysis is still running.

Live evaluation

Not evaluated yet. Workspaces can request a live evaluation.

Security assessment

Scan pending.

Structure

  • No license declaredConfirm you may reuse this skill before importing it into your repository.

SKILL.md

---
name: pipefy-attachments
description: >
  Use this skill when the user wants to upload a file to a Pipefy card or
  table-record attachment field. Covers local and downloaded file sources,
  plus a presigned-URL handshake for uploading files directly.
tags: [pipefy, attachments, upload, card, table-record]
metadata:
  surfaces: "mcp cli"
---

# Attachments

MCP clients: read [references/mcp.md](references/mcp.md). CLI users: read [references/cli.md](references/cli.md). Examples below describe shared operation arguments.

Upload one file at a time to a card or table-record attachment field. The
upload goes through Pipefy's presigned URL flow (request URL, S3 PUT, then
field update).

---

## When to use

- The user says "attach this file to card X" or "upload to the documents field
  on record Y".
- Pick the source by where the bytes actually are. Use the source rules for your chosen surface.

Do not use this skill for:

- Reading or listing existing attachments. There is no list/download tool in
  this skill scope. Cards and table records expose their attachments through
  the regular card/record fetch tools.
- Bulk uploads. One file per call; iterate at the agent layer.

## Prerequisites

- A Pipefy `organization_id`. Find it via `get_organization` or `get_pipe`.
- A target `card_id` or `table_record_id`.
- The attachment field's slug (the human-readable id like `document_upload`,
  not the field's uuid). Find it on the card or table record fetch tools.
- Exactly one file source accessible to the chosen upload surface.

## Tools needed

| Operation | Read-only |
| ------------ | ----------- |
| `upload_attachment_to_card` | No |
| `upload_attachment_to_table_record` | No |
| `create_attachment_presigned_url` | No |

## Steps

### Upload a local file to a card

`file_name` is inferred from the source basename when omitted, so callers
usually only pass the four IDs and the source.

Operation arguments:

```text
upload_attachment_to_card(organization_id=42, card_id=1234, field_id=document_upload, file_path=~/report.pdf)
```

### Upload from a URL

```text
upload_attachment_to_card(organization_id=42, card_id=1234, field_id=document_upload, file_url=https://example.com/report.pdf)
```

When the URL has no filename in its path (e.g. `.../download?id=1`), pass
`file_name` explicitly so Pipefy stores it under a real name.

### Upload a local file to a table record

Operation arguments:

```text
upload_attachment_to_table_record(organization_id=42, table_record_id=tr-555, field_id=document_upload, file_path=/tmp/export.csv)
```

## Overriding the file name

To store the attachment under a different name than the source basename, pass
`file_name` explicitly. It wins over the inferred basename.

```text
upload_attachment_to_card(..., file_url=https://example.com/abc123.pdf, file_name=Invoice-2026.pdf)
```

## Use the presigned handshake

When the one-shot upload cannot reach the bytes or exceeds its 100 MiB cap, use
`create_attachment_presigned_url` and upload from an environment that can read the file:

1. Call `create_attachment_presigned_url` with `organization_id` + `file_name`
   (optional `content_type` / `content_length`). It returns `upload_url` (the S3
   PUT url), `storage_path` (the object key), and `expires_in_seconds`.
2. From an environment that can reach the upload host, HTTP `PUT` the file bytes
   to `upload_url` within `expires_in_seconds` (send `Content-Type` /
   `Content-Length` matching what you passed, if any).
3. Set the attachment field to `[storage_path]` via `update_card_field` /
   `set_table_record_field_value`. Store `storage_path`, never a URL — the signed
   download URL is minted on read.

Because the bytes are handled by the client (step 2), not passed through the
tool call, this keeps the model's context clean.

## Success criteria

**`upload_attachment_to_card` / `upload_attachment_to_table_record`** (one-shot):
the upload result has a `download_url` (the signed URL Pipefy
returns), the inferred or explicit `content_type`, and the `file_size` in
bytes, and the attachment field on the card or record now lists the file. One
call is the whole job.

**`create_attachment_presigned_url`** (handshake) is **not done at mint**:
a successful result here only means a target was minted — no field was touched and
nothing is attached yet. Done means you completed all three steps: after the
client PUTs the bytes to `upload_url` and you set the field to `[storage_path]`,
the attachment field lists the file. Do not treat the mint response (or its
premature signed URL) as a finished upload.

## Failure modes

Check source accessibility, the 100 MiB one-shot limit, upload expiry and signed
headers, and write access to the attachment field. If a signed URL expires,
mint a new one; retrying the PUT against the old URL does not refresh it. The
presigned handshake requires checking the client PUT and field update separately
from minting.

## See also

- `pipefy-pipes-and-cards`: finding card ids and attachment field slugs.
- `pipefy-database-tables`: finding table record ids and field slugs.