# Pin API
## Local Pinning
All commands under `ipfs pin local`
### `add <ipfs-path> [--name=<name>] [--meta=<json>] [--type={recursive, direct}]`
- Name is restricted to UTF-8 and <= 255 characters
- multiple pins can have the same name
- Meta field can be implemented later
- ~~Should error if name is set in meta~~
- Defaults to recursive pin
- Returns
```
type PinOutput struct {
ID string
Name string
Cid string
Type string
Meta string -- future iteration
}
```
- Should we make `add` non-blocking by default and return some Status in all PinOutput objects?
- Status could be an integer for Progress as in the current `ipfs pin add` or could have more fields eg. `{Status : {queued | pinning | pinned | failed}, BlocksDownloaded : int}`
### `ls [--id=<pinid>] [--name=<name> --name-match=<match-type>] [--cid=<ipfs-path>] [--status=<status>] [--meta=<json match expr>] [--type={recursive | direct | recursive, direct}]`
- Returns `PinOutput` for each pin listed
- Must match all criteria
- --name-match="contains" (i.e. case-insensitive, partial or full match) by default, other options for now are "exact"
- should exact also be case insensitive and do we need to add another option if so
- Initial reaction -- case insensitive all the way to minimize surprises with remote API
- Meta field can be implemented later
- need some syntax for the JSON matching -- open to recommendations
- Type option
- Default to recursive, direct
### `rm [--id=<pinid>] [--name=<name> --name-match=<match-type>] [--cid=<ipfs-path>] [--meta=<json match expr>]`
- Returns `PinOutput` for each pin removed
- Must match all criteria
- Meta field can be implemented later
- May delete multiple pins at once
- Any need for --multiple (or --force) to allow deleting multiple pins at once?
- Yes, require `--force` to delete more than one pin
- Failure to pass this would result in an error like "tried to delete 33 pins, to delete them all repeat the command with --multiple", or actually listing all the pins to be deleted
- Any need to specify at least one criteria?
- Yes, but it can be overriden with `--force`
- ~~If no to the above then are we ok with `ipfs pin local rm` deleting all pins? Seems like an easy mistake for a user to make.~~
- Should we allow `--type={recursive, direct}` here to allow removing all recursive or direct pins?
- ~~Note: there is no way to unpin CID `X` as well as all CIDs decended from `X`.~~
- ~~Is this really something people want? Seems pretty niche and counter to what we're trying to get people to do with pins.~~
### Bonus `ipfs add`
- Add `--pin-name` which errors if `--pin=false`
- Modify `AddEvent` to have an extra field `PinID string`
## Remote Pinning
### `add <ipfs-path> [--name=<name>] [--meta=<json>] --service=<service>`
- Name is restricted to UTF-8 and <= 255 characters
- multiple pins can have the same name
- Meta field can be implemented later
- Should error if name is set in meta
- Returns
```
type RemotePinOutput struct {
ID string
Name string
Cid string
Status string
Meta string -- future iteration
Delegates []string
}
```
- Add non-blocking by default
- Should we add a flag to make it block until it's done or failed?
- Should delegates actually be returned to the user?
- If so should they be a separate field or just part of the Meta?
### `ls [--id=<pinid>] [--name=<name> --name-match=<match-type>] [--cid=<ipfs-path>] [--meta=<json match expr>] [--status=<status>] --service=<service>`
- Returns `RemotePinOutput` for each pin listed
- Must match all criteria
- Meta field can be implemented later
### `rm [--id=<pinid>] [--name=<name> --name-match=<match-type>] [--cid=<ipfs-path>] [--meta=<json match expr>] [--status=<status>] --service=<service>`
- Returns `RemotePinOutput` for each pin removed
- Must match all criteria
- Meta field can be implemented later
- May delete multiple pins at once
- Any need for --multiple (or --force) to allow deleting multiple pins at once?
- Failure to pass this would result in an error like "tried to delete 33 pins, to delete them all repeat the command with --multiple", or actually listing all the pins to be deleted
- Any need to specify at least one criteria?
- If no to the above then are we ok with `ipfs pin local rm` deleting all pins? Seems like an easy mistake for a user to make.
## --format
All of the above commands could also take a flag `--format=<format>` so that only selective parts of the PinOutput are returned (e.g. only the name or only the CID).
This doesn't seem required for the first iteration.
## Differences
The differences between local + remote in the two proposed APIs is:
- remote always has `--service`
- if unifying APIs could reserve `--service=local` for local
- remote only has recursive pins
- if unifying APIs could error when type is unsupported
- remote only has name matching type "contains" (is also case-insensitive)
- we may want to select local behavior to plan towards unification (e.g. no case-sensitive matching)
- remote returns delegates
- not sure if it should
- even so could potentially be unified under Meta.Delegates
- Maybe we should update the pinning service API spec to forbid names like Name or Delegates as keys in Meta?
- remote only matches meta exactly
- Question: in the Pinning Service API example does querying for meta={"app_id":"99986338-1113-4706-8302-4420da6158aa"} work when meta has multiple fields? i.e. is the query syntax here to do an exact match on set fields?