openapi: 3.2.0 info: title: Forem API V1 Billboards API version: 1.0.0 description: Access Forem articles, users and other resources via API. servers: - url: https://dev.to description: Production server security: - api-key: [] - bearer_auth: [] tags: - name: billboards paths: /api/billboards: get: summary: Billboards tags: - billboards description: 'Retrieve a list of all billboards configured in the system. ### Billboards Overview: - Billboards are custom promotional ads, notification banners, or call-to-actions shown on the Forem website. - Requires administrative privileges. - Returned objects include layout code, scheduling parameters, geo-targeting configurations, and custom target audience segment associations.' responses: '200': description: successful content: application/json: schema: type: array items: $ref: '#/components/schemas/Billboard' '401': description: unauthorized operationId: getApiBillboards x-operation-id-source: derived post: summary: Create a billboard tags: - billboards description: 'Create a new billboard. ### Parameter Options & Tips: - **body_markdown**: The HTML/Markdown advertisement copy. - **placement_area**: Target region in layouts (e.g. `post_comments` below comments, `sidebar` in sidebars, `home_feed` between posts). - **display_to**: Cohort target rules (e.g. `all` for everyone, `logged_in`, `guests`, or customized segments). - **target_geolocations**: Comma-separated ISO codes for country/region targeting. - **approved** & **published**: Set to `true` to activate billboard rotation instantly.' parameters: [] responses: '201': description: A billboard content: application/json: schema: type: object items: $ref: '#/components/schemas/Billboard' '401': description: unauthorized '422': description: unprocessable requestBody: content: application/json: schema: type: object items: $ref: '#/components/schemas/Billboard' description: Billboard parameters. operationId: postApiBillboards x-operation-id-source: derived /api/billboards/{id}: get: summary: A billboard (by id) tags: - billboards description: Retrieve full configurations of a single billboard by ID. Requires admin credentials. parameters: - name: id in: path required: true description: The ID of the billboard. schema: type: integer format: int32 minimum: 1 example: 123 responses: '200': description: successful '401': description: unauthorized '404': description: Unknown Billboard ID operationId: getApiBillboardsById x-operation-id-source: derived put: summary: Update a billboard by ID tags: - billboards description: 'Update an existing billboard''s configurations. ### Integration Guidance: - Allows changing placement area, geolocations, target segments, or text copy. - Updating an active billboard takes effect instantly in the layout delivery cache.' parameters: - name: id in: path required: true description: The ID of the billboard to update. schema: type: integer format: int32 minimum: 1 example: 123 responses: '200': description: successful content: application/json: schema: type: object items: $ref: '#/components/schemas/Billboard' '404': description: not found '401': description: unauthorized requestBody: content: application/json: schema: type: object items: $ref: '#/components/schemas/Billboard' description: Billboard updated attributes. operationId: putApiBillboardsById x-operation-id-source: derived /api/billboards/{id}/unpublish: put: summary: Unpublish a billboard tags: - billboards description: 'Remove a billboard from active rotation by unpublishing it. ### Usage: - Instantly disables display across all pages while keeping the configuration stored in the database for later reactivations or historical reporting.' parameters: - name: id in: path required: true description: The ID of the billboard to unpublish. schema: type: integer format: int32 minimum: 1 example: 123 responses: '204': description: no content '404': description: not found '401': description: unauthorized operationId: putApiBillboardsByIdUnpublish x-operation-id-source: derived components: schemas: Billboard: description: Billboard, aka Widget, ex. Display Ad type: object properties: id: type: integer description: The ID of the Billboard name: type: string description: For internal use, helps distinguish ads from one another body_markdown: type: string description: The text (in markdown) of the ad (required) approved: type: boolean description: Ad must be both published and approved to be in rotation published: type: boolean description: Ad must be both published and approved to be in rotation expires_at: type: - string - 'null' format: date-time description: Timestamp when the billboard expires. After this time, the billboard will automatically be marked as not approved. organization_id: type: - integer - 'null' description: Identifies the organization to which the ad belongs creator_id: type: - integer - 'null' description: Identifies the user who created the ad. placement_area: type: string enum: - sidebar_left - sidebar_left_2 - sidebar_right - sidebar_right_second - sidebar_right_third - feed_first - feed_second - feed_third - home_hero - footer - page_fixed_bottom - post_fixed_bottom - post_body_bottom - post_sidebar - post_comments - post_comments_mid - digest_first - digest_second description: Identifies which area of site layout the ad can appear in tag_list: type: string description: Tags on which this ad can be displayed (blank is all/any tags) exclude_article_ids: type: - string - 'null' description: Articles this ad should *not* appear on (blank means no articles are disallowed, and this ad can appear next to any/all articles). Comma-separated list of integer Article IDs audience_segment_id: type: integer description: Specifies a specific audience segment who will see this billboard audience_segment_type: type: string enum: - manual - trusted - posted - no_posts_yet - dark_theme - light_theme - no_experience - experience1 - experience2 - experience3 - experience4 - experience5 description: Specifies a group of users who will see this billboard (must match audience_segment_id if both provided) target_geolocations: type: array items: type: string description: Locations to show this billboard in (blank means it will be shown in all locations). Specified as a comma-separated list or array of ISO 3166-2 country and optionally region codes) display_to: type: string enum: - all - logged_in - logged_out default: all description: Potentially limits visitors to whom the ad is visible type_of: type: string enum: - in_house - community - external default: in_house description: 'Types of the billboards: in_house (created by admins), community (created by an entity, appears on entity''s content), external ( created by an entity, or a non-entity, can appear everywhere) ' required: - name - body_markdown - placement_area securitySchemes: api-key: type: apiKey name: api-key in: header description: "API Key authentication.\n\nAuthentication for some endpoints, like write operations on the\nArticles API require a DEV API key.\n\nAll authenticated endpoints are CORS disabled, the API key is intended for non-browser scripts.\n\n### Getting an API key\n\nTo obtain one, please follow these steps:\n\n - visit https://dev.to/settings/extensions\n - in the \"DEV API Keys\" section create a new key by adding a\n description and clicking on \"Generate API Key\"\n\n ![obtain a DEV API Key](https://user-images.githubusercontent.com/37842/172718105-bd93664e-76e0-477d-99c4-265dda0b06c5.png)\n\n - You'll see the newly generated key in the same view\n ![generated DEV API Key](https://user-images.githubusercontent.com/37842/172718151-e7fe26a0-9937-42e8-96c6-333acdab9e49.png)" bearer_auth: type: http scheme: bearer bearerFormat: JWT description: Short-lived RS256 RFC 9068 access token issued by the configured delegation service and verified against its configured JWKS. The issuer authorizes the client and requested operation before minting the token; Forem validates the token and resolves its subject and owner to a local user. An invalid token returns 401; an unavailable trust dependency with no usable cached key returns 503.