Cogram · Schema
ProjectV1
Project response.
Artificial IntelligenceArchitectureEngineeringDocumentationCollaboration
Properties
| Name | Type | Description |
|---|---|---|
| id | string | |
| name | string | |
| description | object | |
| external_id | object | Your system's ID for this project. |
| client_name | object | |
| project_address | object | |
| is_active | boolean | False once the project is archived. |
| email_filing_enabled | boolean | |
| meeting_filing_enabled | boolean | Whether Cogram suggests this project for meetings and, where the organization allows it, files meetings into it. Only takes effect while the organization has meeting filing turned on. Filing a meeting |
| is_public | boolean | If true, project appears in org project directory; non-members can request access. |
| unanet_project_id | object | Unanet ERP A/E project id, for projects synced from Unanet; null for every other project. Stable across customer re-codes, so join on this rather than on external_id. |
| unanet_lead_stage | object | Unanet lead/pursuit stage name (e.g. "06-Submitted Proposal"). Set means an open opportunity; null means a normal project. |
| unanet_custom_fields | object | The project's Unanet user-defined fields, keyed by Unanet fieldName. Replaced in full on each sync, so a cleared field disappears. |
| unanet_market_sectors | object | The project's Unanet market sectors and their percentage split, in Unanet's order. Null for projects that aren't synced from Unanet or have no sectors. |
| created_at | string | |
| updated_at | object | Tracks the project record only — not the emails, RFIs, meetings or other records filed under it. Null if never updated. |
| related_counts | object | Per-type counts of records filed under this project. Present only when the request asked for it with ?include=counts; null otherwise, so existing callers pay nothing for it. |
| members | object | Users holding a role on this project, ordered by email. Present only when the request asked for it with ?include=members; null otherwise, so existing callers pay nothing for it. An empty list means th |
JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "https://artifacts.apis.io/cogram-com/json-schema/cogram-com-project-v1-schema.json",
"title": "ProjectV1",
"description": "Project response.",
"x-generated": "2026-11-04",
"x-method": "derived",
"x-generator": "derive-json-schema.py",
"x-source": "openapi/api.cogram.com-v1-openapi.json#/components/schemas/ProjectV1",
"properties": {
"id": {
"type": "string",
"title": "Id"
},
"name": {
"type": "string",
"title": "Name"
},
"description": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Description"
},
"external_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "External Id",
"description": "Your system's ID for this project."
},
"client_name": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Client Name"
},
"project_address": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Project Address"
},
"is_active": {
"type": "boolean",
"title": "Is Active",
"description": "False once the project is archived."
},
"email_filing_enabled": {
"type": "boolean",
"title": "Email Filing Enabled"
},
"meeting_filing_enabled": {
"type": "boolean",
"title": "Meeting Filing Enabled",
"description": "Whether Cogram suggests this project for meetings and, where the organization allows it, files meetings into it. Only takes effect while the organization has meeting filing turned on. Filing a meeting here by hand works either way."
},
"is_public": {
"type": "boolean",
"title": "Is Public",
"description": "If true, project appears in org project directory; non-members can request access."
},
"unanet_project_id": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Unanet Project Id",
"description": "Unanet ERP A/E project id, for projects synced from Unanet; null for every other project. Stable across customer re-codes, so join on this rather than on external_id."
},
"unanet_lead_stage": {
"anyOf": [
{
"type": "string"
},
{
"type": "null"
}
],
"title": "Unanet Lead Stage",
"description": "Unanet lead/pursuit stage name (e.g. \"06-Submitted Proposal\"). Set means an open opportunity; null means a normal project."
},
"unanet_custom_fields": {
"anyOf": [
{
"additionalProperties": true,
"type": "object"
},
{
"type": "null"
}
],
"title": "Unanet Custom Fields",
"description": "The project's Unanet user-defined fields, keyed by Unanet fieldName. Replaced in full on each sync, so a cleared field disappears."
},
"unanet_market_sectors": {
"anyOf": [
{
"items": {
"$ref": "#/$defs/ProjectMarketSectorV1"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Unanet Market Sectors",
"description": "The project's Unanet market sectors and their percentage split, in Unanet's order. Null for projects that aren't synced from Unanet or have no sectors."
},
"created_at": {
"type": "string",
"format": "date-time",
"title": "Created At"
},
"updated_at": {
"anyOf": [
{
"type": "string",
"format": "date-time"
},
{
"type": "null"
}
],
"title": "Updated At",
"description": "Tracks the project record only — not the emails, RFIs, meetings or other records filed under it. Null if never updated."
},
"related_counts": {
"anyOf": [
{
"$ref": "#/$defs/ProjectRelatedCountsV1"
},
{
"type": "null"
}
],
"description": "Per-type counts of records filed under this project. Present only when the request asked for it with ?include=counts; null otherwise, so existing callers pay nothing for it."
},
"members": {
"anyOf": [
{
"items": {
"$ref": "#/$defs/ProjectMemberSummaryV1"
},
"type": "array"
},
{
"type": "null"
}
],
"title": "Members",
"description": "Users holding a role on this project, ordered by email. Present only when the request asked for it with ?include=members; null otherwise, so existing callers pay nothing for it. An empty list means the project genuinely has no members — distinguishable from null, which means they were not requested. Group-granted access is not listed; only direct per-user roles are."
}
},
"type": "object",
"required": [
"id",
"name",
"description",
"external_id",
"client_name",
"project_address",
"is_active",
"email_filing_enabled",
"meeting_filing_enabled",
"is_public",
"unanet_project_id",
"unanet_lead_stage",
"unanet_custom_fields",
"unanet_market_sectors",
"created_at",
"updated_at"
],
"$defs": {
"ProjectMarketSectorV1": {
"properties": {
"name": {
"type": "string",
"title": "Name",
"description": "Sector name as configured in Unanet, e.g. \"Healthcare\"."
},
"pct": {
"anyOf": [
{
"type": "number"
},
{
"type": "null"
}
],
"title": "Pct",
"description": "Percent of the project attributed to this sector."
}
},
"type": "object",
"required": [
"name"
],
"title": "ProjectMarketSectorV1",
"description": "One Unanet market sector on a project, with the share of the project\nattributed to it. Reported exactly as Unanet holds it — Cogram neither\nnormalizes the percentages nor requires them to add up."
},
"ProjectMemberRoleV1": {
"type": "string",
"enum": [
"MEMBER",
"OWNER",
"LEAD",
"VIEWER"
],
"title": "ProjectMemberRoleV1",
"description": "Per-project role: OWNER manages membership, LEAD manages the project but not\nmembership, MEMBER read/write, VIEWER read-only."
},
"ProjectMemberSummaryV1": {
"properties": {
"user_id": {
"type": "string",
"format": "uuid",
"title": "User Id"
},
"email": {
"type": "string",
"title": "Email"
},
"role": {
"$ref": "#/$defs/ProjectMemberRoleV1"
}
},
"type": "object",
"required": [
"user_id",
"email",
"role"
],
"title": "ProjectMemberSummaryV1",
"description": "One member inside a project response, as returned by\n``?include=members``.\n\nNarrower than ``ProjectMemberV1`` from ``GET /projects/{id}/members``,\nwhich also carries first and last name: a roster embedded in every row of a\n100-project page pays for each field it carries, and display names are not\nwhat the roster is read for. Fetch the dedicated members endpoint for those.\n\n``user_id`` stays, though, because ``email`` cannot stand in for it. Two\naccounts may share an address (see ``User``), so an email-only entry is\nambiguous exactly when it matters, and it is ``user_id`` that the write\nside — ``PUT``/``DELETE /projects/{id}/members/{user_id}`` — is keyed by."
},
"ProjectRelatedCountsV1": {
"properties": {
"emails": {
"type": "integer",
"title": "Emails",
"default": 0
},
"documents": {
"type": "integer",
"title": "Documents",
"default": 0
},
"drawings": {
"type": "integer",
"title": "Drawings",
"default": 0
},
"drawing_sets": {
"type": "integer",
"title": "Drawing Sets",
"default": 0
},
"submittals": {
"type": "integer",
"title": "Submittals",
"default": 0
},
"rfis": {
"type": "integer",
"title": "Rfis",
"default": 0
},
"meetings": {
"type": "integer",
"title": "Meetings",
"default": 0
},
"reports": {
"type": "integer",
"title": "Reports",
"default": 0
},
"observations": {
"type": "integer",
"title": "Observations",
"default": 0
},
"transmittals": {
"type": "integer",
"title": "Transmittals",
"default": 0
}
},
"type": "object",
"title": "ProjectRelatedCountsV1",
"description": "How many records of each type the project holds.\n\nEvery field defaults to 0, so a project with nothing filed under it\nreturns zeros rather than omitting keys.\n\nCounts cover the record types an all-time export of the same project\nships, with one exception: soft-deleted meetings are excluded, because\nthey are absent from every other read path. An export narrowed to a time\nrange ships a subset of what is counted here. Cogram's seeded example\nrecords are counted; they are real rows in the project.\n\nUsable as a change signal: poll, compare against the previous values, and\nre-export the projects that moved. Three classes of change are invisible\nto it, because cardinality does not move — an in-place edit (a renamed\ndocument, a corrected email subject); a new revision of an existing\ndrawing, or action items generated for an existing meeting, since only\nthe top-level record is counted; and an add plus a delete inside the same\npolling window, which nets to zero."
}
}
}
Work with this as data
Every JSON Schema here is available over the APIs.io API and to AI agents over MCP.
MCP server
One button, every client — Claude, Cursor, VS Code and the rest.
https://apis.io/mcp
Tools for schemas
4 MCP tools reach this
find_json_schemasBrowse and filter every JSON Schema in the catalog.apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.resolveTurn a domain, URL or GitHub org into the provider it belongs to.find_cohortsEvery scored population of providers in the catalog.
Call it yourself
curl for this page
This JSON Schema
curl "https://apis.io/api/v1/json-schemas/cogram-com-project-v1"
All schemas
curl "https://apis.io/api/v1/json-schemas?limit=25"
Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.
Get an API key
Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.
A second provider on the same verified email joins the account you already have.