{
   "components" : {
      "schemas" : {
         "contacts.contact.address.v1" : {
            "properties" : {
               "city" : {
                  "example" : "Lebanon"
               },
               "country" : {
                  "description" : "Leave this field blank (absent, empty string, or null) if the contact is in the United States.\n\nFor non-US addresses, use the English name of the country (e.g. Germany rather than Deutschland). Place other elements of the address in the `city`, `state`, and `postal_code` fields normally.\n\nFor example, even though German address blocks include the postal code before the city name, keep the city in the `city` field and the postal code in the `postal_code` field. Our software automatically reformats international addresses as needed when printing envelopes.",
                  "example" : ""
               },
               "postal_code" : {
                  "example" : "03766"
               },
               "state" : {
                  "example" : "NH"
               },
               "street" : {
                  "description" : "The street address may contain multiple lines.",
                  "example" : "123 Main St."
               }
            },
            "type" : "object"
         },
         "contacts.contact.update.v1" : {
            "properties" : {
               "address" : {
                  "$ref" : "#/components/schemas/contacts.contact.address.v1"
               },
               "company" : {
                  "description" : "The contact's company, church, or other organization. It will be printed beneath the name and above the street address.",
                  "example" : null
               },
               "external_id" : {
                  "description" : "Use this field to store your application's identifier for this contact.",
                  "example" : null
               },
               "file_as" : {
                  "description" : "The name we should use when showing this contact in a list. It is usually in the format `LastName, FirstName` for individuals, or just the regular name for companies and churches.\n\nIf the `file_as` parameter is not included, one will be generated automatically, based on the contact's name.",
                  "example" : "Tischler, Joe"
               },
               "greeting" : {
                  "description" : "The name we should use in the first line of a mail-merged letter, usually following the word \"Dear\".\n\nIf a 'greeting' isn't included, one will be generated automatically, based on the contact's name.",
                  "example" : "Joe and Mary"
               },
               "name" : {
                  "description" : "The contact's full name, as it should appear on the first line of an envelope.",
                  "example" : "Joe and Mary Tischler"
               }
            },
            "type" : "object"
         },
         "contacts.contact.v1" : {
            "properties" : {
               "address" : {
                  "$ref" : "#/components/schemas/contacts.contact.address.v1"
               },
               "company" : {
                  "description" : "The contact's company, church, or other organization. It will be printed beneath the name and above the street address.",
                  "example" : null
               },
               "contact_id" : {
                  "example" : "c-###-####",
                  "type" : "string"
               },
               "external_id" : {
                  "description" : "Use this field to store your application's identifier for this contact.",
                  "example" : null
               },
               "file_as" : {
                  "description" : "The name we should use when showing this contact in a list. It is usually in the format `LastName, FirstName` for individuals, or just the regular name for companies and churches.\n\nIf the `file_as` parameter is not included, one will be generated automatically, based on the contact's name.",
                  "example" : "Tischler, Joe"
               },
               "greeting" : {
                  "description" : "The name we should use in the first line of a mail-merged letter, usually following the word \"Dear\".\n\nIf a 'greeting' isn't included, one will be generated automatically, based on the contact's name.",
                  "example" : "Joe and Mary"
               },
               "name" : {
                  "description" : "The contact's full name, as it should appear on the first line of an envelope.",
                  "example" : "Joe and Mary Tischler"
               }
            },
            "type" : "object"
         },
         "contacts.contact_created.v1" : {
            "properties" : {
               "contact_id" : {
                  "example" : "c-###-####",
                  "type" : "string"
               }
            },
            "type" : "object"
         },
         "contacts.contact_created.v2" : {
            "properties" : {
               "contact_id" : {
                  "example" : "c-###-####",
                  "type" : "string"
               },
               "external_id" : {}
            },
            "type" : "object"
         },
         "contacts.contact_wrapper.v1" : {
            "properties" : {
               "contact" : {
                  "$ref" : "#/components/schemas/contacts.contact.v1",
                  "description" : "A contact object."
               }
            },
            "type" : "object"
         },
         "contacts.contacts_created.v1" : {
            "properties" : {
               "contacts" : {
                  "items" : {
                     "$ref" : "#/components/schemas/contacts.contact_created.v2"
                  },
                  "type" : "array"
               }
            },
            "type" : "object"
         },
         "contacts.v1" : {
            "properties" : {
               "contacts" : {
                  "description" : "An array of contact objects.",
                  "items" : {
                     "$ref" : "#/components/schemas/contacts.contact.v1"
                  },
                  "type" : "array"
               }
            },
            "type" : "object"
         },
         "contacts.webhook.address_update.v1" : {
            "properties" : {
               "code" : {
                  "description" : "The type of event that triggered this webhook.  This code is intended for use by your app and should generally not be displayed to users.\n\nThe following codes are currently in use:\n\n- `unspecified`: The address was updated without a reason   being provided. The accompanying message will typically be   blank, but may contain a message, and should be displayed   to the end user if present.\n\n- `api_client`: The address was updated by an API client.\n\n- `returned_mail`: A letter was returned to us. It may   include a forwarding address.\n\nIn order to allow the list of codes to expand over time, your application MUST treat any unrecognized code as `unspecified`.",
                  "example" : "returned_mail"
               },
               "contact_id" : {
                  "description" : "The contact ID used by prayerletters.com",
                  "example" : "c-###-####",
                  "type" : "string"
               },
               "external_id" : {
                  "description" : "The contact ID supplied by your integration (or whichever integration created the contact)."
               },
               "message" : {
                  "description" : "A single line of free-form text providing more detail about the event and new address.  This is intended to be displayed to users to provide information about why the event was triggered.  It is often a custom message typed by one of our employees and should not be parsed by your app.",
                  "example" : "Letter Returned -- Undeliverable As Addressed"
               },
               "name" : {
                  "description" : "The contact's full name, as it should appear on the first line of an envelope.",
                  "example" : "Joe and Mary Tischler"
               },
               "new_address" : {
                  "$ref" : "#/components/schemas/contacts.webhook.address_update.v1.address",
                  "description" : "The updated address record.\n\nUse the `is_deliverable` field to determine whether or not the new address is valid.  For example, if we receive a move-update notice saying that a PO Box was closed and no new address was provided, `is_deliverable` will be false.",
                  "example" : {
                     "city" : "Lebanon",
                     "country" : "",
                     "is_deliverable" : false,
                     "postal_code" : "03766",
                     "state" : "NH",
                     "street" : "123 Main St."
                  }
               },
               "old_address" : {
                  "$ref" : "#/components/schemas/contacts.webhook.address_update.v1.address",
                  "description" : "The address record as it existed prior to the change.\n\nNote that the `is_deliverable` field does not indicate whether the old address was deliverable, but rather whether it was considered to be deliverable before the event that triggered this webhook.\n\nFor example, if we receive a returned letter without a forwarding address, we will send an address update event with the same old and new address.  In this case, `is_deliverable` will be true in `old_address` and false in `new_address`.",
                  "example" : {
                     "city" : "Lebanon",
                     "country" : "",
                     "is_deliverable" : true,
                     "postal_code" : "03766",
                     "state" : "NH",
                     "street" : "123 Main St."
                  }
               },
               "updated" : {
                  "description" : "When the event was triggered.  You should check to ensure that the user hasn't changed the address in your app between when the event was created and when the webhook arrived at your app, in case of delayed messages.",
                  "format" : "date-time",
                  "type" : "string"
               }
            },
            "type" : "object"
         },
         "contacts.webhook.address_update.v1.address" : {
            "properties" : {
               "city" : {
                  "example" : "Lebanon"
               },
               "country" : {
                  "example" : ""
               },
               "is_deliverable" : {
                  "description" : "Whether or not we consider the address to be valid for receiving mail."
               },
               "postal_code" : {
                  "example" : "03766"
               },
               "state" : {
                  "example" : "NH"
               },
               "street" : {
                  "example" : "123 Main St."
               }
            },
            "type" : "object"
         },
         "files.file.v1" : {
            "properties" : {
               "download_href" : {
                  "example" : "/api/v1/files/f-###-####/download",
                  "format" : "uri",
                  "type" : "string"
               },
               "filename" : {
                  "example" : "newsletter.pdf"
               },
               "id" : {
                  "example" : "f-###-####",
                  "type" : "string"
               }
            },
            "type" : "object"
         },
         "files.file_uploaded.v1" : {
            "properties" : {
               "filename" : {
                  "example" : "myfile.pdf"
               },
               "id" : {
                  "example" : "f-###-####",
                  "type" : "string"
               }
            },
            "type" : "object"
         },
         "hooks.hook.v1" : {
            "properties" : {
               "event" : {
                  "description" : "The name of webhook that this subscription follows."
               },
               "href" : {
                  "description" : "The URL of this webhook subscription.  To delete or make changes to the webhook, you would make a DELETE or POST call to this URL.",
                  "example" : "/api/v1/hooks/h-###-####",
                  "format" : "uri",
                  "type" : "string"
               },
               "id" : {
                  "example" : "h-###-####",
                  "type" : "string"
               },
               "last_triggered" : {
                  "description" : "The last time this subscription received an event.  This timestamp is set when the event is generated, not when the webhook target is successfully contacted.",
                  "format" : "date-time",
                  "type" : "string"
               },
               "target" : {
                  "description" : "The URL to be notified when the requested event is triggered.  It must be an HTTP or HTTPS address and may contain query parameters.",
                  "example" : "https://example.com/api/hooks?token=abc123",
                  "format" : "uri",
                  "type" : "string"
               }
            },
            "type" : "object"
         },
         "hooks.ping_response.v1" : {
            "properties" : {
               "status" : {
                  "description" : "The HTTP status code returned by the webhook subscription's target upon receiving the ping event.",
                  "example" : "200"
               }
            },
            "type" : "object"
         },
         "hooks.v1" : {
            "properties" : {
               "events" : {
                  "additionalProperties" : {
                     "$ref" : "#/components/schemas/hooks.v1.event"
                  },
                  "type" : "object"
               },
               "subscriptions" : {
                  "items" : {
                     "$ref" : "#/components/schemas/hooks.hook.v1"
                  },
                  "type" : "array"
               }
            },
            "type" : "object"
         },
         "hooks.v1.event" : {
            "properties" : {
               "description" : {
                  "description" : "A brief description of the event that triggers the webhook."
               },
               "url" : {
                  "description" : "A web page describing the webhook.",
                  "format" : "uri",
                  "type" : "string"
               }
            },
            "type" : "object"
         },
         "orders.resend_created.v1" : {
            "properties" : {
               "created" : {
                  "format" : "date-time",
                  "type" : "string"
               },
               "order_id" : {
                  "example" : "m-###-####",
                  "type" : "string"
               }
            },
            "type" : "object"
         },
         "orders.resend_to_list.v1" : {
            "properties" : {
               "list_id" : {
                  "example" : "l-###-####",
                  "type" : "string"
               },
               "saved_order_id" : {
                  "example" : "l-###-####",
                  "type" : "string"
               }
            },
            "type" : "object"
         },
         "orders.saved_order.v1" : {
            "properties" : {
               "created" : {
                  "format" : "date-time",
                  "type" : "string"
               },
               "name" : {},
               "saved_order_id" : {
                  "example" : "l-###-####",
                  "type" : "string"
               }
            },
            "type" : "object"
         },
         "orders.saved_orders.v1" : {
            "properties" : {
               "saved_orders" : {
                  "description" : "An array of saved order objects.",
                  "items" : {
                     "$ref" : "#/components/schemas/orders.saved_order.v1"
                  },
                  "type" : "array"
               }
            },
            "type" : "object"
         },
         "orders.webhook.canceled.v1" : {
            "properties" : {
               "canceled" : {
                  "format" : "date-time",
                  "type" : "string"
               },
               "created" : {
                  "format" : "date-time",
                  "type" : "string"
               },
               "order_id" : {
                  "example" : "m-###-####",
                  "type" : "string"
               }
            },
            "type" : "object"
         },
         "orders.webhook.file_attached.v1" : {
            "properties" : {
               "created" : {
                  "format" : "date-time",
                  "type" : "string"
               },
               "file_id" : {
                  "example" : "f-###-####",
                  "type" : "string"
               },
               "filename" : {},
               "order_id" : {
                  "example" : "m-###-####",
                  "type" : "string"
               },
               "size" : {}
            },
            "type" : "object"
         },
         "orders.webhook.list_imported.v1" : {
            "properties" : {
               "created" : {
                  "format" : "date-time",
                  "type" : "string"
               },
               "list_imported" : {
                  "format" : "date-time",
                  "type" : "string"
               },
               "order_id" : {
                  "example" : "m-###-####",
                  "type" : "string"
               },
               "recipient_count" : {}
            },
            "type" : "object"
         },
         "orders.webhook.order_complete.v1" : {
            "properties" : {
               "completed" : {
                  "format" : "date-time",
                  "type" : "string"
               },
               "order_id" : {
                  "example" : "m-###-####",
                  "type" : "string"
               }
            },
            "type" : "object"
         },
         "orders.webhook.order_created.v1" : {
            "properties" : {
               "created" : {
                  "format" : "date-time",
                  "type" : "string"
               },
               "order_id" : {
                  "example" : "m-###-####",
                  "type" : "string"
               }
            },
            "type" : "object"
         },
         "templates.webhook.shipped.v1.customer" : {
            "properties" : {
               "id" : {
                  "example" : "s-###-####",
                  "type" : "string"
               },
               "name" : {
                  "example" : "Joe Carpenter"
               }
            },
            "type" : "object"
         },
         "templates.webhook.shipped.v1.order" : {
            "properties" : {
               "created" : {
                  "format" : "date",
                  "type" : "string"
               },
               "id" : {
                  "example" : "m-###-####",
                  "type" : "string"
               },
               "quantity" : {
                  "example" : 100
               },
               "shipped" : {
                  "format" : "date",
                  "type" : "string"
               }
            },
            "type" : "object"
         },
         "templates.webhook.shipped.v1.template" : {
            "properties" : {
               "code" : {
                  "example" : "event_postcard"
               },
               "id" : {
                  "example" : "t-###-####",
                  "type" : "string"
               },
               "name" : {
                  "example" : "Special Event Invitation Postcard"
               }
            },
            "type" : "object"
         }
      },
      "securitySchemes" : {
         "access_token" : {
            "description" : "An OAuth access token may be provided as part of the URL query. This is less secure than using a bearer token since the URL gets logged, but it's convenient for testing from a browser or command line.\n\nWe recommend that this method only be used during development.",
            "in" : "query",
            "name" : "access_token",
            "type" : "apiKey"
         },
         "bearer_token" : {
            "description" : "This is the recommended way to provide an access token received via OAuth.  If your HTTP library doesn't support the Bearer method, you may instead pass it as the username portion of the Basic method (leave the password blank).",
            "scheme" : "bearer",
            "type" : "http"
         },
         "oauth" : {
            "description" : "API access is provided using OAuth 2.0.  If you don't yet have client credentials for accessing the API, contact us with your desired use case and we'll be happy to get you set up.",
            "flows" : {
               "authorizationCode" : {
                  "authorizationUrl" : "https://www.prayerletters.com/my/oauth/authorize",
                  "scopes" : {
                     "app.admin.read" : "Read site settings",
                     "app.admin.write" : "Modify site settings",
                     "contacts.read" : "Access your mailing list",
                     "contacts.write" : "Change your mailing list",
                     "files.read" : "See files that have been uploaded to your account",
                     "files.write" : "Add files to your account",
                     "hooks.manage" : "Update and delete webhooks created by other applications",
                     "lists.read" : "Access your temporary mailing lists",
                     "lists.write" : "Create and update temporary mailing lists",
                     "orders.read" : "Access your order information",
                     "orders.write" : "Create orders on your behalf"
                  },
                  "tokenUrl" : "https://www.prayerletters.com/oauth/token"
               }
            },
            "type" : "oauth2"
         }
      }
   },
   "info" : {
      "title" : "Prayer Letter Service API",
      "version" : "0.1"
   },
   "openapi" : "3.1.0",
   "paths" : {
      "/v1/contacts" : {
         "delete" : {
            "description" : "This call is included for the sake of completeness, but it should almost never actually be used. If you upload a new set of contacts using PUT, any existing contacts will automatically be removed.",
            "responses" : {
               "204" : {
                  "description" : "Successful response"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "contacts.write"
                  ]
               }
            ],
            "summary" : "Delete all contacts",
            "tags" : [
               "contacts"
            ]
         },
         "get" : {
            "description" : "Download the active mailing list.",
            "responses" : {
               "200" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/contacts.v1"
                        }
                     }
                  },
                  "description" : "Successful Response"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "contacts.read"
                  ]
               }
            ],
            "summary" : "Get all contacts",
            "tags" : [
               "contacts"
            ]
         },
         "put" : {
            "description" : "Remove all current contacts and upload a new mailing list.\n\nThe body of the request should be formatted identically to the response from the GET call.\n\nWhen you include a non-null `external_id` field with a record, the response will contain a mapping between your ID and the `contact_id` at prayerletters.com. You can then use the `contact_id` to update or delete the record as needed.",
            "requestBody" : {
               "content" : {
                  "application/json" : {
                     "schema" : {
                        "$ref" : "#/components/schemas/contacts.v1"
                     }
                  }
               }
            },
            "responses" : {
               "200" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/contacts.contacts_created.v1"
                        }
                     }
                  },
                  "description" : "Successful Response"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "contacts.write"
                  ]
               }
            ],
            "summary" : "Replace the mailing list",
            "tags" : [
               "contacts"
            ]
         }
      },
      "/v1/contacts/{id}" : {
         "delete" : {
            "description" : "Remove a contact from the database.",
            "parameters" : [
               {
                  "description" : "The ID of the contact to be deleted, as returned by GET. It typically follows the format `c-###-####`, but is not guaranteed to do so, and should be treated as an opaque string.",
                  "in" : "path",
                  "name" : "id",
                  "required" : true,
                  "schema" : {
                     "example" : "c-###-####",
                     "type" : "string"
                  }
               }
            ],
            "responses" : {
               "204" : {
                  "description" : "Successful response.\n\nWe keep a record of deleted contacts, and will also return status 204 (No Content) if the contact previously existed but has already been deleted."
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "contacts.write"
                  ]
               }
            ],
            "summary" : "Delete a contact",
            "tags" : [
               "contacts"
            ]
         },
         "get" : {
            "description" : "Retrieve a single mailing list contact.",
            "parameters" : [
               {
                  "description" : "The ID of the contact to be retrieved. It typically follows the format `c-###-####`, but is not guaranteed to do so, and should be treated as an opaque string.",
                  "in" : "path",
                  "name" : "id",
                  "required" : true,
                  "schema" : {
                     "example" : "c-###-####",
                     "type" : "string"
                  }
               }
            ],
            "responses" : {
               "200" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/contacts.contact.v1"
                        }
                     }
                  },
                  "description" : "Successful Response"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "contacts.read"
                  ]
               }
            ],
            "summary" : "Get a contact",
            "tags" : [
               "contacts"
            ]
         }
      },
      "/v1/files" : {
         "post" : {
            "parameters" : [
               {
                  "example" : "myfile.pdf",
                  "in" : "query",
                  "name" : "filename",
                  "required" : true,
                  "schema" : {
                     "type" : "string"
                  }
               }
            ],
            "requestBody" : {
               "content" : {
                  "*/*" : {}
               },
               "description" : "Include the contents of the file as the request body.  The content type header will be ignored; we use the file extension to determine the file type.",
               "required" : true
            },
            "responses" : {
               "201" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/files.file_uploaded.v1"
                        }
                     }
                  },
                  "description" : "Successful response"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "files.write"
                  ]
               }
            ],
            "summary" : "Upload a file",
            "tags" : [
               "files"
            ]
         }
      },
      "/v1/files/{id}" : {
         "delete" : {
            "description" : "Delete a file that hasn't yet been associated with an order.",
            "parameters" : [
               {
                  "description" : "The ID of the file.  It typically follows the format `f-###-####`, but is not guaranteed to do so.",
                  "in" : "path",
                  "name" : "id",
                  "required" : true,
                  "schema" : {
                     "example" : "f-###-####",
                     "type" : "string"
                  }
               }
            ],
            "responses" : {
               "204" : {
                  "description" : "This response code will also be used if the file doesn't exist or was previously deleted."
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "files.write"
                  ]
               }
            ],
            "summary" : "Delete a file",
            "tags" : [
               "files"
            ]
         },
         "get" : {
            "description" : "Retrieve information about an uploaded file.",
            "parameters" : [
               {
                  "description" : "The ID of the file.  It typically follows the format `f-###-####`, but is not guaranteed to do so.",
                  "in" : "path",
                  "name" : "id",
                  "required" : true,
                  "schema" : {
                     "example" : "f-###-####",
                     "type" : "string"
                  }
               }
            ],
            "responses" : {
               "200" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/files.file.v1"
                        }
                     }
                  },
                  "description" : "Successful Response"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "files.read"
                  ]
               }
            ],
            "summary" : "Get File Metadata",
            "tags" : [
               "files"
            ]
         }
      },
      "/v1/files/{id}/download" : {
         "get" : {
            "parameters" : [
               {
                  "description" : "The ID of the file.  It typically follows the format `f-###-####`, but is not guaranteed to do so.",
                  "in" : "path",
                  "name" : "id",
                  "required" : true,
                  "schema" : {
                     "example" : "f-###-####",
                     "type" : "string"
                  }
               }
            ],
            "responses" : {
               "200" : {
                  "description" : "The response body will contain the contents of the file.  See the Content-Disposition header for the filename."
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "files.read"
                  ]
               }
            ],
            "summary" : "Download a file",
            "tags" : [
               "files"
            ]
         }
      },
      "/v1/hooks" : {
         "get" : {
            "description" : "This will give you a list of events to which your API token can subscribe, as well as a list of existing subscriptions. If you have the `hooks.manage` scope, you will see all webhook subscriptions; otherwise, you'll only see subscriptions that you've created.",
            "responses" : {
               "200" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/hooks.v1"
                        }
                     }
                  },
                  "description" : "Successful Response"
               }
            },
            "summary" : "Get information about all webhooks and subscriptions.",
            "tags" : [
               "hooks"
            ]
         },
         "post" : {
            "description" : "Subscribe to receive notifications about an event.\n\nWhen a webhook subscription is created, we will immediately trigger an asynchronous ping event at the target URL, so that you can be sure the subscription is working. See the [Ping a webhook target][ping] API call for details. Unlike normal notifications, this event will not be retried if there's an error.\n\n[ping]: /dev/api/v1/hooks/:id/ping/GET",
            "parameters" : [
               {
                  "description" : "If provided, notifications will include an Authorization header with this Bearer token.",
                  "in" : "query",
                  "name" : "bearer_token",
                  "schema" : {
                     "type" : "string"
                  }
               },
               {
                  "description" : "The name of the webhook event.",
                  "in" : "query",
                  "name" : "event",
                  "schema" : {
                     "type" : "string"
                  }
               },
               {
                  "description" : "The URL that should be notified when the event occurs.  The URL may contain query parameters, though a parameter will be overwritten if it has the same name as a query parameter provided by the webhook.",
                  "in" : "query",
                  "name" : "target",
                  "schema" : {
                     "type" : ".uri"
                  }
               }
            ],
            "responses" : {
               "201" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/hooks.hook.v1"
                        }
                     }
                  },
                  "description" : "Successful Response"
               }
            },
            "summary" : "Subscribe to receive notifications about an event.",
            "tags" : [
               "hooks"
            ]
         }
      },
      "/v1/hooks/{id}" : {
         "delete" : {
            "description" : "Delete a webhook subscription.",
            "parameters" : [
               {
                  "in" : "path",
                  "name" : "id",
                  "required" : true,
                  "schema" : {
                     "example" : "h-###-####",
                     "type" : "string"
                  }
               }
            ],
            "responses" : {
               "204" : {
                  "description" : "Successful Response"
               }
            },
            "summary" : "Delete a webhook",
            "tags" : [
               "hooks"
            ]
         },
         "get" : {
            "description" : "Retrieve details about a webhook subscription.",
            "parameters" : [
               {
                  "in" : "path",
                  "name" : "id",
                  "required" : true,
                  "schema" : {
                     "example" : "h-###-####",
                     "type" : "string"
                  }
               }
            ],
            "responses" : {
               "200" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/hooks.hook.v1"
                        }
                     }
                  },
                  "description" : "Successful Response"
               }
            },
            "summary" : "Get a webhook",
            "tags" : [
               "hooks"
            ]
         },
         "post" : {
            "description" : "Change the target URL for a webhook subscription.\n\nIt isn't currently possible to change the event for a given webhook subscription.  If you need to do this, create a new subscription and delete the old one.",
            "parameters" : [
               {
                  "description" : "Notifications will include an Authorization header with this Bearer token.  To remove an existing token, include this parameter with an empty string as its value.  If not present, the existing value will be retained.",
                  "in" : "query",
                  "name" : "bearer_token",
                  "schema" : {
                     "type" : "string"
                  }
               },
               {
                  "in" : "path",
                  "name" : "id",
                  "required" : true,
                  "schema" : {
                     "example" : "h-###-####",
                     "type" : "string"
                  }
               },
               {
                  "description" : "The URL that should be notified when the event occurs.  The URL may contain query parameters, though a parameter will be overwritten if it has the same name as a query parameter provided by the webhook.",
                  "in" : "query",
                  "name" : "target",
                  "schema" : {
                     "type" : ".uri"
                  }
               }
            ],
            "responses" : {
               "200" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/hooks.hook.v1"
                        }
                     }
                  },
                  "description" : "Successful Response"
               }
            },
            "summary" : "Change the target URL for a webhook subscription",
            "tags" : [
               "hooks"
            ]
         }
      },
      "/v1/hooks/{id}/ping" : {
         "get" : {
            "description" : "Triggers a webhook on demand, for testing purposes.\n\nYou can call this URL from your browser or from a command line (don't forget to include your `access_token` in the URL as well), and we will immediately and synchronously send a `ping` event to the webhook subscription's target URL.\n\nThe HTTP status code that your app returns to us will be displayed as the status field in the response.\n\nThis is a one-time notification, and will not be retried if it fails or times out.",
            "parameters" : [
               {
                  "in" : "path",
                  "name" : "id",
                  "required" : true,
                  "schema" : {
                     "example" : "h-###-####",
                     "type" : "string"
                  }
               }
            ],
            "responses" : {
               "200" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/hooks.ping_response.v1"
                        }
                     }
                  },
                  "description" : "Successful Response"
               }
            },
            "summary" : "Ping a webhook target",
            "tags" : [
               "hooks"
            ]
         }
      },
      "/v1/orders" : {
         "post" : {
            "description" : "Create an order based on an existing saved order and a new mailing list.",
            "requestBody" : {
               "content" : {
                  "application/json" : {
                     "schema" : {
                        "$ref" : "#/components/schemas/orders.resend_to_list.v1"
                     }
                  }
               }
            },
            "responses" : {
               "201" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/orders.resend_created.v1"
                        }
                     }
                  },
                  "description" : "Successful Response"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "orders.write"
                  ]
               }
            ],
            "summary" : "Create an order",
            "tags" : [
               "orders"
            ]
         }
      },
      "/v1/orders/saved" : {
         "get" : {
            "description" : "Retrieve a list of saved orders.\n\n_Note:_ For accounts with a large number of saved orders (\"large\" isn't specified, but is at least more than 25), only a subset of orders will be returned by this call.  If you expect this to become an issue, contact us and we'll add details about accessing multiple pages of results.",
            "responses" : {
               "200" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/orders.saved_orders.v1"
                        }
                     }
                  },
                  "description" : "Successful Response"
               }
            },
            "summary" : "List saved orders",
            "tags" : [
               "orders"
            ]
         }
      },
      "/v1/orders/{id}.pdf" : {
         "get" : {
            "description" : "Retrieve the preview PDF of an order.",
            "parameters" : [
               {
                  "description" : "The ID of the order to be retrieved.",
                  "in" : "path",
                  "name" : "id",
                  "required" : true,
                  "schema" : {
                     "example" : "m-###-####",
                     "type" : "string"
                  }
               }
            ],
            "responses" : {
               "200" : {
                  "description" : "The body will be the content of the PDF."
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "orders.read"
                  ]
               }
            ],
            "summary" : "Retrieve a preview PDF",
            "tags" : [
               "orders"
            ]
         }
      },
      "/v2/contacts" : {
         "post" : {
            "description" : "Create a new contact.",
            "requestBody" : {
               "content" : {
                  "application/json" : {
                     "schema" : {
                        "$ref" : "#/components/schemas/contacts.contact_wrapper.v1"
                     }
                  }
               }
            },
            "responses" : {
               "200" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/contacts.contact_created.v1"
                        }
                     }
                  },
                  "description" : "Successful Response"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "contacts.write"
                  ]
               }
            ],
            "summary" : "Add a contact",
            "tags" : [
               "contacts"
            ]
         }
      },
      "/v2/contacts/{id}" : {
         "post" : {
            "description" : "Update an existing contact in the database.\n\nThe request body should be a JSON object containing the contact to be updated. All attributes are optional. Any omitted attributed will be left unchanged.",
            "requestBody" : {
               "content" : {
                  "application/json" : {
                     "schema" : {
                        "$ref" : "#/components/schemas/contacts.contact_wrapper.v1"
                     }
                  }
               }
            },
            "responses" : {
               "204" : {
                  "description" : "Successful Response"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "contacts.write"
                  ]
               }
            ],
            "summary" : "Update a contact",
            "tags" : [
               "contacts"
            ]
         }
      },
      "/v3/contacts" : {
         "post" : {
            "description" : "Create a new contact.",
            "requestBody" : {
               "content" : {
                  "application/json" : {
                     "schema" : {
                        "$ref" : "#/components/schemas/contacts.contact.v1"
                     }
                  }
               }
            },
            "responses" : {
               "200" : {
                  "content" : {
                     "application/json" : {
                        "schema" : {
                           "$ref" : "#/components/schemas/contacts.contact_created.v1"
                        }
                     }
                  },
                  "description" : "Successful Response"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "contacts.write"
                  ]
               }
            ],
            "summary" : "Add a contact",
            "tags" : [
               "contacts"
            ]
         }
      },
      "/v3/contacts/{id}" : {
         "post" : {
            "description" : "Update an existing contact in the database.\n\nThe request body should be a JSON object containing the contact object attributes to be updated. All attributes are optional. Any omitted attributed will be left unchanged.",
            "parameters" : [
               {
                  "description" : "The ID of the contact to be retrieved. It typically follows the format `c-###-####`, but is not guaranteed to do so, and should be treated as an opaque string.",
                  "in" : "path",
                  "name" : "id",
                  "required" : true,
                  "schema" : {
                     "example" : "c-###-####",
                     "type" : "string"
                  }
               }
            ],
            "requestBody" : {
               "content" : {
                  "application/json" : {
                     "schema" : {
                        "$ref" : "#/components/schemas/contacts.contact.update.v1"
                     }
                  }
               }
            },
            "responses" : {
               "204" : {
                  "description" : "Successful Response"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "contacts.write"
                  ]
               }
            ],
            "summary" : "Update a contact",
            "tags" : [
               "contacts"
            ]
         }
      }
   },
   "servers" : [
      {
         "url" : "https://www.prayerletters.com/api"
      }
   ],
   "tags" : [
      {
         "name" : "orders"
      },
      {
         "description" : "The Contacts API allows you to upload and download the entire contact database. You can also add, update, and remove individual contacts from the database.\n\nIt's best to make changes using the Contacts API before an order is submitted. Some changes that are made to the contact database may affect existing orders, but we do not currently guarantee that a change will or will not affect an order; to change an existing order, we recommend having the user contact us directly.\n\n(We may provide stronger guarantees in the future, particularly if we're pestered to do so.)",
         "name" : "contacts"
      },
      {
         "description" : "Webhooks let you subscribe to the events that interest you, and we'll notify you when they happen. This eliminates the need for polling, and provides your app (and therefore your app's users) with real-time updates.\n\nIf you want to implement a feature in your app that currently requires polling our site for information, please contact us about setting up a webhook for the appropriate event.\n\n## Notifications\n\nWhen a webhook is triggered, we will send an HTTP POST request to the target URL that you've registered.\n\nThe request will always contain an `event` query parameter containing the event that triggered the webhook. Typically, each request will also contain a JSON body with more information, as well as a small set of query parameters that will provide context in case your app isn't able to read the body of the request.\n\nYour application should return a `200 OK` or `204 No Content` response to indicate that you've successfully received the notification, but any 200-series status will be accepted.\n\n## Retries\n\nIf your app isn't available or returns an error when a webhook is triggered, we will retry at increasing intervals for up to a week. Note that this can lead to notifications coming in out of order.\n\n## Handling Loops\n\nSome integrations will have API calls that trigger webhook events. For example, an app that manages a mailing list sends address updates via the API, which will trigger a the address update webhook.\n\nIn these cases, there will be a `loopback_token` and/or `loopback_client` parameter in the URL indicating that the event was triggered by the same token or client, respectively. If the webhook has a JSON body, there will also be a field with the same name and a true value at the top level of the object.\n\nYou can use these two fields to filter out activity that you initiated, or to verify that it has happened.",
         "name" : "hooks"
      }
   ],
   "webhooks" : {
      "contacts.address_update.v1" : {
         "post" : {
            "description" : "Triggered when a contact's address is updated.\n\nNote: This webhook will not be triggered when a contact is added or deleted from the mailing list, nor will it be triggered when an address is changed for a single mailing.\n\nTypical triggers include filling in missing information such as ZIP codes, providing notifications about returned mail, and sending address updates from the National Change of Address database.",
            "parameters" : [
               {
                  "description" : "The contact ID used by prayerletters.com.",
                  "in" : "query",
                  "name" : "contact_id",
                  "schema" : {
                     "example" : "c-###-####",
                     "type" : "string"
                  }
               },
               {
                  "description" : "The contact ID supplied by your integration (or whichever integration created the contact).",
                  "in" : "query",
                  "name" : "external_id",
                  "schema" : {
                     "type" : "string"
                  }
               }
            ],
            "requestBody" : {
               "content" : {
                  "application/json" : {
                     "schema" : {
                        "$ref" : "#/components/schemas/contacts.webhook.address_update.v1"
                     }
                  }
               }
            },
            "responses" : {
               "2XX" : {
                  "description" : "Return a 200-series status code (200 and 204 being\nthe most common) to indicate that your app has\nsuccessfully received the webhook event.\n"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "contacts.read"
                  ]
               }
            ],
            "summary" : "Address Updated"
         }
      },
      "orders.order_complete.v1" : {
         "post" : {
            "description" : "Triggered when production for an order is complete.\n\nNote: Orders will be shipped or mailed at the next opportunity once production is complete, which may not be the same day if the mail collection has already occurred or if a \"hold until\" date has been set.\n\nNote: This webhook will not be triggered when an order is canceled.",
            "parameters" : [
               {
                  "in" : "query",
                  "name" : "order_id",
                  "schema" : {
                     "example" : "m-###-####",
                     "type" : "string"
                  }
               }
            ],
            "requestBody" : {
               "content" : {
                  "application/json" : {
                     "schema" : {
                        "$ref" : "#/components/schemas/orders.webhook.order_complete.v1"
                     }
                  }
               }
            },
            "responses" : {
               "2XX" : {
                  "description" : "Return a 200-series status code (200 and 204 being\nthe most common) to indicate that your app has\nsuccessfully received the webhook event.\n"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "orders.read"
                  ]
               }
            ],
            "summary" : "Order Complete"
         }
      },
      "orders.order_created.v1" : {
         "post" : {
            "description" : "Triggered when a print order is created for any type of order that is shown on the Order History page.",
            "parameters" : [
               {
                  "in" : "query",
                  "name" : "order_id",
                  "schema" : {
                     "example" : "m-###-####",
                     "type" : "string"
                  }
               }
            ],
            "requestBody" : {
               "content" : {
                  "application/json" : {
                     "schema" : {
                        "$ref" : "#/components/schemas/orders.webhook.order_created.v1"
                     }
                  }
               }
            },
            "responses" : {
               "2XX" : {
                  "description" : "Return a 200-series status code (200 and 204 being\nthe most common) to indicate that your app has\nsuccessfully received the webhook event.\n"
               }
            },
            "security" : [
               {
                  "access_token" : []
               },
               {
                  "bearer_token" : []
               },
               {
                  "oauth" : [
                     "orders.read"
                  ]
               }
            ],
            "summary" : "Order Created"
         }
      }
   }
}
