openapi: 3.2.0 info: title: 'FlipperForce Public Project Updates: Photos API' version: 0.0.10 description: '# FlipperForce Public API • Version 1 ## How do I request an API key? 1. [Request a Public API key.](https://tools.flipperforce.com/integrations) 2. Use the API key as an Authorization HTTP header with Bearer token: `Authorization: Bearer token-goes-here` ## Support / Help * Email: support@flipperforce.com * Chat: https://tools.flipperforce.com/ ## Rate Limits If you encounter a `429 Too Many Requests` response, you have submitted too many requests in a short amount of time. Please decrease the amount or frequency of your requests and try again. ## Changelog ### July 25, 2026 - v0.0.10 * Add support for [Activity Log](/operations/v1.workspace.activity-log.list). ### July 23, 2026 - v0.0.9 * Response format of `created_at` and `updated_at` fields now include microseconds. Old format: `2026-06-14T15:30:45Z` and new format: `2026-06-14T15:30:45.123456Z` ### July 21, 2026 - v0.0.8 * OpenAPI spec documents Bearer Token authentication strategy ### June 22, 2026 - v0.0.6 * Add support for [Project Income](/operations/v1.project.income.list). * [Create Upload Intent](/operations/v1.workspace.upload-intent.create) properly documents API response code as 201 Created instead of 200 OK. ### June 21, 2026 - v0.0.4 * Add support for [Project Expenses: Transactions](/operations/v1.project.expense-transactions.list). * Add support for [Project Expenses: Line Items](/operations/v1.project.expense-line-items.list). ### June 4, 2026 - v0.0.3 * Add support for [Project Expenses: Categories](/operations/v1.project.expense-categories.list). ### June 2, 2026 - v0.0.2 * Add support for [Expense Accounts](/operations/v1.workspace.expense-accounts.list). * Add support for [Companies](/operations/v1.workspace.companies.list). * Add support for [Company Categories](/operations/v1.workspace.companies.categories.list). ### September 3, 2025 - v0.0.1 * [Project Photo Log: Photos - Create](/operations/v1.project.photo-log.create) added support for ordering Photos by EXIF timestamp via parameter `photo_timestamp`. ### August 13, 2025 * [Create Upload Intent API](/operations/v1.workspace.upload-intent.create) now requires a new POST parameter `upload_type` noting the uploaded file''s use case. ' servers: - url: https://tools.flipperforce.com/api/v1 security: - PublicApiBearerAuth: [] tags: - name: 'Project Updates: Photos' paths: /project/{projectV1}/updates/{updateUuid}/photos: post: operationId: v1.project.updates.photos.create description: 'Attach a Photo to this Update using an uploaded photo from an [Upload Intent](/operations/v1.workspace.upload-intent.create) or an existing Photo such as from the [Photo Log](/operations/v1.project.photo-log.list). Photos can originate from several use cases: * Upload Intent - Submit `intent_uuid` to use a newly uploaded photo * Existing File - Submit `file_uuid` to use an existing File. Note: the File must already be associated with this Project. Submitting a `file_uuid` will duplicate that File on the backend so it can be included in the Progress Update. The returned `data.photo.uuid` will not be the submitted `file_uuid` because it is the duplicated File.' summary: Create tags: - 'Project Updates: Photos' parameters: - name: projectV1 in: path required: true description: Project UUID schema: type: string format: uuid - name: updateUuid in: path required: true description: Project Update UUID to add Photos to schema: type: string format: uuid requestBody: content: application/json: schema: type: object properties: intent_uuid: type: string description: 'Optional. Submit this or `file_uuid`. [Upload Intent](/operations/v1.workspace.upload-intent.create) with a recently uploaded photo.' file_uuid: type: string description: 'Optional. Submit this or `intent_uuid`. [File](/schemas/File) from another use case, such as a File from a Photo Log Photo. Note that this is the low-level File UUID, not the Photo Log Photo UUID. For example, submit `photo_log_photo.photo.uuid` and not `photo_log_photo.uuid`' photo_order: type: integer description: 'Optional. Sequence this Photo should be displayed relative to other photos that have the same Photo Date. If left blank, photo will display before other existing photos.' responses: '201': description: '`Project Update: Photo`' content: application/json: schema: type: object properties: data: $ref: '#/components/schemas/Project_Update__Photo' required: - data '422': $ref: '#/components/responses/ValidationException' '401': $ref: '#/components/responses/AuthenticationException' '403': description: When the authenticated User Account is forbidden from accessing the content or software features content: application/json: schema: type: object properties: message: type: string description: Human-readable description of why access was not allowed reason: type: - string - 'null' description: 'Machine-readable code for why access was not allowed. Possible values: * `UNKNOWN` - Access Forbidden * `UNSUPPORTED_CLIENT` - Unsupported client. * `SUBSCRIPTION_MISSING` - A Subscription is required. Visit the application website to manage the Subscription. * `SUBSCRIPTION_PAYMENT_DUE` - A paid Subscription is required. Visit the application website to manage the Subscription. * `SUBSCRIPTION_PLAN_UNSUPPORTED_FEATURE` - The Subscription Plan does not support using this Software Feature. * `FEATURE_ACCESS_DENIED` - Your account within this Workspace is not allowed to use this Software Feature. Contact the Workspace Owner to request access. * `PROJECT_ACCESS_DENIED` - Your account is not allowed to access this Project. Contact the Workspace Owner to request access. * `PROJECT_ARCHIVED` - This Project is Archived and cannot be accessed. You must restore this Project to Active Status to use it. * `WORKSPACE_ACCESS_DENIED` - You do not have an account within this Workspace. * `WORKSPACE_SELECTION_MISSING` - You must select a Workspace before making this request. ' enum: - UNKNOWN - UNSUPPORTED_CLIENT - SUBSCRIPTION_MISSING - SUBSCRIPTION_PAYMENT_DUE - SUBSCRIPTION_PLAN_UNSUPPORTED_FEATURE - FEATURE_ACCESS_DENIED - PROJECT_ACCESS_DENIED - PROJECT_ARCHIVED - WORKSPACE_ACCESS_DENIED - WORKSPACE_SELECTION_MISSING - null /project/{projectV1}/updates/photos/{photoUuid}: delete: operationId: v1.project.updates.photos.destroy description: 'Remove photo from a Progress Update. The Photo will remain available in FlipperForce within Project Documents, but will not be listed with the Progress Update.' summary: Remove tags: - 'Project Updates: Photos' parameters: - name: projectV1 in: path required: true description: Project UUID schema: type: string format: uuid - name: photoUuid in: path required: true description: Project Update Photo UUID to delete schema: type: string format: uuid responses: '204': description: No content '404': $ref: '#/components/responses/ModelNotFoundException' '401': $ref: '#/components/responses/AuthenticationException' '403': description: When the authenticated User Account is forbidden from accessing the content or software features content: application/json: schema: type: object properties: message: type: string description: Human-readable description of why access was not allowed reason: type: - string - 'null' description: 'Machine-readable code for why access was not allowed. Possible values: * `UNKNOWN` - Access Forbidden * `UNSUPPORTED_CLIENT` - Unsupported client. * `SUBSCRIPTION_MISSING` - A Subscription is required. Visit the application website to manage the Subscription. * `SUBSCRIPTION_PAYMENT_DUE` - A paid Subscription is required. Visit the application website to manage the Subscription. * `SUBSCRIPTION_PLAN_UNSUPPORTED_FEATURE` - The Subscription Plan does not support using this Software Feature. * `FEATURE_ACCESS_DENIED` - Your account within this Workspace is not allowed to use this Software Feature. Contact the Workspace Owner to request access. * `PROJECT_ACCESS_DENIED` - Your account is not allowed to access this Project. Contact the Workspace Owner to request access. * `PROJECT_ARCHIVED` - This Project is Archived and cannot be accessed. You must restore this Project to Active Status to use it. * `WORKSPACE_ACCESS_DENIED` - You do not have an account within this Workspace. * `WORKSPACE_SELECTION_MISSING` - You must select a Workspace before making this request. ' enum: - UNKNOWN - UNSUPPORTED_CLIENT - SUBSCRIPTION_MISSING - SUBSCRIPTION_PAYMENT_DUE - SUBSCRIPTION_PLAN_UNSUPPORTED_FEATURE - FEATURE_ACCESS_DENIED - PROJECT_ACCESS_DENIED - PROJECT_ARCHIVED - WORKSPACE_ACCESS_DENIED - WORKSPACE_SELECTION_MISSING - null components: responses: ValidationException: description: Validation error content: application/json: schema: type: object properties: message: type: string description: Errors overview. errors: type: object description: A detailed description of each field that failed validation. additionalProperties: type: array items: type: string required: - message - errors ModelNotFoundException: description: Not found content: application/json: schema: type: object properties: message: type: string description: Error overview. required: - message AuthenticationException: description: Unauthenticated content: application/json: schema: type: object properties: message: type: string description: Error overview. required: - message schemas: File: type: object properties: uuid: type: string description: Public identifier name: type: string description: 'Short human-readable description to distinguish this file from other files across the entire Project' size: type: integer description: File size in bytes type: type: string description: 'Roughly what kind of file is available. Such as `pdf` or `jpeg`. Note that this is not a file MIME-type, but can be used by clients to change how they handle the file.' source_url: type: object description: URLs to full versions of the file properties: view: type: string description: URL to view the file on the device, as an inline HTTP response download: type: string description: URL to download the file, as a download HTTP response required: - view - download preview_url: type: object description: 'URLs to view smaller versions of the file''s contents. Images will return a smaller version of the image itself. Documents will return a placeholder document image and not the file''s actual contents.' properties: thumbnail: type: string description: Up to approximately 300px wide large: type: string description: Up to approximately 600px wide required: - thumbnail - large required: - uuid - name - size - type - source_url - preview_url title: File Project_Update__Photo: type: object properties: uuid: type: string description: Unique identifier order: type: integer description: 'Order number for displaying this photo relative to others. Photos are not guaranteed to have sequential ordering (i.e. 1, 2, 3, etc). A Photo with `order` of `5` should display before another Photo with `order` of `10`.' photo: description: Photo details $ref: '#/components/schemas/File' required: - uuid - order - photo title: 'Project Update: Photo' securitySchemes: PublicApiBearerAuth: type: http description: 'Use the Public API key provided by FlipperForce as a Bearer token. Send the key exactly as provided in the Authorization header: `Authorization: Bearer `.' scheme: bearer bearerFormat: FlipperForce Public API key