---
# System prepended metadata

title: tbDEX PFI RESTful API

---

# tbDEX PFI RESTful API

[ToC]

# Authentication

> :information_source:  TODO: Discuss Authn for GET requests

The client must provide proof of control of the DID that initiated an RFQ (the `from` DID) in order to make a GET request for data relating to that specific thread. 

The requester populates the Authorization header with a Bearer token consisting of JWS containing a nonce signed by the requester's DID. 

---

# Error Responses
* An error response is one whose status code is `>= 400`.
* If present, the body of an error response will conform to the following:

| Field                | Description                                                                                                                                                                                                                       |
|----------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| `id`                 | A unique identifier for this particular occurrence of the problem.                                                                                                                                                                |
| `status`             | The HTTP status code applicable to this problem, expressed as a string value. This SHOULD be provided.                                                                                                                            |
| `code`               | An application-specific error code, expressed as a string value.                                                                                                                                                                  |
| `title`              | A short, human-readable summary of the problem that SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization.                                                                           |
| `detail`             | A human-readable explanation specific to this occurrence of the problem. Like `title`, this field’s value can be localized.                                                                                                       |
| `source`             | An object containing references to the primary source of the error. It should include the `pointer`, `parameter`, or `header` members or be omitted.                                                                              |
| `source.pointer`     | A JSON Pointer to the value in the request document that caused the error. This MUST point to a value in the request document that exists; if it doesn’t, the client SHOULD simply ignore the pointer.                            |
| `source.parameter`   | A string indicating which URI query parameter caused the error.                                                                                                                                                                  |
| `source.header`      | A string indicating the name of a single request header which caused the error.                                                                                                                                                  |
| `meta`               | A meta object containing non-standard meta-information about the error.                                                                                                                                                          |


```typescript=
type ErrorObject = {
  id?: string
  status: string
  code?: string
  title?: string
  detail?: string
  source?: {
    pointer?: string
    parameter?: string
    header?: string
  }
  meta?: Record<string, any>
}

type ErrorResponseBody = {
  errors: Error[]
}
```

---

# Query Params

Query parameters, also known as query strings, are a way to send additional information to the server as part of a URL. They allow clients to provide specific input or customize the server's response. Query parameters typically follow the main URL and start with a `?` character. They consist of key-value pairs, and multiple pairs can be separated by `&` characters

Query params are supported by many of the `GET /${resource}` endpoints in the following ways

* Simple Example: `?simple=field`
* Same Field; Multiple Values: `field=value&field=anotherValue`

## Pagination

Pagination is supported using the following query params:



| Param          | Description                                                                 | Default |
| -------------- | --------------------------------------------------------------------------- | ------- |
| `page[offset]` | Specifies the starting position from where the records should be retrieved. | `0`     |
| `page[limit]`  | Specifies the maximum number of records to be retrieved.                    | `10`    | 

### Example
`/?page[offset]=0&page[limit]=10`

---

# Idempotency
The IDs of individual tbDEX messages are used as idempotency keys

---

# Metadata
Each tbDEX message POST request body and responses from the PFI containing tbDEX messages will include the following fields:
> :information_source:  TODO: link docs from tbdex-protocol repo

Example:
```
  id          : 'tbdex:close:837',
  type        : 'close',
  threadId    : 'tbdex:rfq:123',
  parentId    : 'tbdex:quote:456',
  from        : 'did:ion:fdsjaklfdsa',
  to          : 'did:ion:teuwoipew',
  createdTime : '2023-06-26T12:34:56Z'
  jws         : 'ajhakuejakhefa'
```
___

# Offerings

The `Offering` resource is used to convey the currency pairs a PFI is _offering_. It includes information about payment methods and associated fees.

## List Offerings

### Description
Used to fetch offerings from a PFI

### Endpoint
`GET /offerings`

### Query Params


| Param           | Description                                                                         |
| --------------- | ----------------------------------------------------------------------------------- |
| `baseCurrency`  | The primary currency listed in a currency pair, representing the unit being traded. **This is the currency that Alice will be _receiving_** |
| `quoteCurrency` | The secondary currency listed in a currency pair, indicating its value in relation to the base currency. **This is the currency that the PFI will be _receiving_**                            |
| `payinMethodKind` | The payin method Alice wishes to use to provide quote currency |
| `payoutMethodKind` | The payout method Alice wishes to use to receive base currency |
| `id` | Query for a specific offering                            |


### Response
| Status             | Body                  |
| ------------------ | --------------------- |
| `200: OK`          | `Offering[]`          | 
| `400: Bad Request` | `{ errors: Error[] }` |


---

# Threads
A thread is a series of linked tbDEX messages between Alice and a PFI for a single exchange. A thread can be created by submitting an RFQ.

## Submit RFQ

### Endpoint
`POST /threads/:thread_id/rfq`

### RFQ Request Body
> :information_source: same as in tbdex-protocol

### Response
| Status             | Body                  |
| ------------------ | --------------------- |
| `202: Accepted`    | N/A                   | 
| `400: Bad Request` | `{ errors: Error[] }` |

### Errors
| Status | Description            |
| ------ | ---------------------- |
| 400    | Validation error(s)    | 
| 400    | Failed Signature Check |
| 404    | Thread not found       |
| 409    | RFQ already exists     |
| 409    | Thread already exists  |

## Get Quote
### Endpoint
`GET /threads/:thread_id/?messageType=quote`

### Response
| Status             | Body                              |
| ------------------ | --------------------------------- |
| `200: OK`          | `{ data: TbdexMessage<Quote>[] }` | 
| `400: Bad Request` | `{ errors: Error[] }`             |

### Quote response body
> :information_source: same as in tbdex-protocol


## Submit Order

### Endpoint
`POST /threads/:thread_id/order`

### Order Request Body
> :information_source: same as in tbdex-protocol
```
{
  ...metadata,
  "parentId": "tbdex:quote:123",
}
```


### Response
| Status             | Body                  |
| ------------------ | --------------------- |
| `202: Accepted`    | N/A                   | 
| `400: Bad Request` | `{ errors: Error[] }` |



### Errors

| Status | Description                                                             |
| ------ | ----------------------------------------------------------------------- |
| 400    | Failed Signature Check                                                  |
| 404    | Thread not found                                                        |
| 409    | Order already exists                                                    |
| 409    | Order not allowed (e.g. bc thread was closed or bc no quote exists yet) | 

## Submit Close

### Description
Closes the thread. Indicates that Alice is no longer interested

### Endpoint
`POST /threads/:thread_id/close`

### Request Body
> :information_source:  TODO: add Close example


### Response
| Status             | Body                  |
| ------------------ | --------------------- |
| `202: Accepted`    | N/A                   | 
| `400: Bad Request` | `{ errors: Error[] }` |



### Errors

| Status | Description            |
| ------ | ---------------------- |
| 400    | Failed Signature Check |
| 404    | Thread not found       |
| 409    | Close not allowed      | 


---

## Get Thread

### Description
Retrieves the thread specified by ID and messageType

### Authentication

### Endpoint
`GET /threads/:id`


### Query Params
| Param         | Description                   |
| ------------- | ----------------------------- |
| `messageType` | filters the messages returned | 


### Response

| Status             | Body                       |
| ------------------ | -------------------------- |
| `200: OK`          | `{ data: TbdexMessage[] }` | 
| `400: Bad Request` | `{ errors: Error[] }`      |
| `404: Not Found`   | N/A                        |

---

## List Threads

> :information_source: DESCOPED FOR PIGEON

### Description
Returns an array containing IDs of threads started by the requesting DID

### Endpoint
`GET /threads`

### Response
| Status             | Body                  |
| ------------------ | --------------------- |
| `200: OK.     `    | `{ data: string[]}`   | 
| `400: Bad Request` | `{ errors: Error[] }` |

### Query Params

| Param | Description      |
| ----- | ---------------- |
| sort  | field to sort by | 



# References
* JSON:API spec: https://jsonapi.org/format/