Korely

Projects

A project is an organizational workspace in your Korely account that groups your API keys. For an agent builder, projects answer a concrete ops question: how do you run a staging environment and a production environment under one account, with separate keys, separate usage views, and a clear promotion path, without risking a staging write leaking into the production memory your end users see? The answer is two projects, one key each. Every account starts with a Default project created automatically; you mint additional projects in the dashboard as your deployment topology grows.

Projects are an organizational layer on top of your keys. They do not change how your agents call Korely, and they are not something an agent ever sees. A project is resolved on the server from the key that authenticates the request.

flowchart TD
    ACC["Your account"]
    P1["Project: Staging"]
    P2["Project: Production"]
    K1["kor_live_staging_..."]
    K2["kor_live_prod_..."]
    A1["agent_id: support-bot-staging"]
    A2["agent_id: support-bot"]
    U1["user_id: test-customer-001"]
    U2["user_id: customer-4812"]

    ACC --> P1
    ACC --> P2
    P1 --> K1
    P2 --> K2
    K1 --> A1
    K2 --> A2
    A1 --> U1
    A2 --> U2

    style ACC fill:#1e293b,color:#e2e8f0,stroke:#6366f1
    style P1 fill:#374151,color:#d1d5db,stroke:#4b5563
    style P2 fill:#374151,color:#d1d5db,stroke:#4b5563
    style K1 fill:#1e293b,color:#a5b4fc,stroke:#6366f1
    style K2 fill:#1e293b,color:#a5b4fc,stroke:#6366f1
    style A1 fill:#0f172a,color:#94a3b8,stroke:#334155
    style A2 fill:#0f172a,color:#94a3b8,stroke:#334155
    style U1 fill:#0f172a,color:#94a3b8,stroke:#334155
    style U2 fill:#0f172a,color:#94a3b8,stroke:#334155
Two projects under one account. Each project owns its keys and the data they write; agent_id and user_id scope data within the project.

Managed from the dashboard

Projects live in the dashboard, not the public API. There is no /projects endpoint and your agents never create or select a project. From the dashboard you:

  • Create, rename, archive, and delete projects.
  • Create API keys inside a specific project, reading and writing or read only or write only.
  • Move a key from one project to another. This is the staging → production path: promote a key once it is ready instead of minting a new one and re-deploying.

Deleting a project never deletes a live key. When you delete a project, its keys are re-pointed to the Default project and keep working, so a cleanup in the dashboard never takes a running agent offline. By default its memories and facts move to the Default project with them, so nothing is lost. If you choose to erase them instead, they are deleted for good, with an audit record.

Project vs agent_id vs user_id

Three different things group your data, at three different levels. They stack; they do not compete.

ConceptGroupsSet whereUse it for
Project Your API keys Dashboard Environment and product: staging vs production, one product vs another.
agent_id One application, within a project API call The app itself, e.g. support-bot. One project runs many agents.
user_id The memory of one end customer API call The person your agent serves (Mem0-style). Unlimited on every tier.

Read it top to bottom: a project is the environment or product container that holds your keys; agent_id is the application within that project; user_id is the end user that application is serving. Use projects for environment and product, agent_id for the app, and user_id for the end user.

What a project isolates

A project groups your keys, gives you a place to read usage per project, lets you promote a key from staging to production, and walls off the data. Every memory and fact carries the project of the key that wrote it, and a key reads, searches, assembles context from, corrects, forgets and erases only what belongs to its own project. A staging key never sees production memory, and a fact in another project answers 404, the same answer as an id that never existed.

Erasing an end user is per project too. DELETE /v1/users/{end_user}/memories erases that end user in the key's project. If the same end user lives in several projects, call it once per project, with that project's key.

Quotas and the agent cap are account-wide. Staging and production share one write pool and one read pool; there is no per-project budget. The agent cap counts agent_id names across the account: a name used in two projects holds one slot, and GET /v1/agents lists the names of the key's project while its used count covers the whole account.

The public API is unchanged

Projects do not touch the /v1 contract. There is no project field in any request body, and there is nothing new to send. The project a request belongs to is resolved server-side from the authenticating key; agents stay exactly as they are.

Terminal window
# The same call from a staging key and a production key.
# The project is resolved from the key: nothing changes in the request.
curl https://api.korely.ai/v1/memories \
-H "Authorization: Bearer kor_live_..." \
-H "Content-Type: application/json" \
-d '{"content": "User prefers email follow-ups", "user_id": "customer-4812"}'

Because the project is carried by the key, you get isolation simply by minting keys in different projects. Mint a staging key in a Staging project and a production key in a Production project, point each environment at its own key, and the separation follows automatically with no code change: separate keys, separate usage views, separate memory, and the staging → production promotion path.

Worked example: staging to production

The following shows the full lifecycle an agent builder goes through when moving a support bot from staging to production. The API calls are identical in both environments; only the key changes.

from korely_memory import Korely
# ── Staging environment ─────────────────────────────────────────────────────
# Key is scoped to the "Staging" project in the dashboard.
staging = Korely(api_key="kor_live_staging_...")
staging.add(
"Test user verified the support-bot correctly recalled meal preference.",
user_id="test-customer-001",
agent_id="support-bot-staging",
)
results = staging.search(
"meal preference",
user_id="test-customer-001",
agent_id="support-bot-staging",
)
# results[0].snippet => "Test user verified the support-bot correctly..."
# ── Production environment ───────────────────────────────────────────────────
# When staging tests pass, swap the key for the one in the "Production" project.
# No code change required, the project is resolved server-side from the key.
production = Korely(api_key="kor_live_prod_...")
production.add(
"Customer-4812 prefers vegetarian meals. Mentioned nut allergy.",
user_id="customer-4812",
agent_id="support-bot",
)
facts = production.get_facts(
user_id="customer-4812",
agent_id="support-bot",
)
# get_facts returns a flat list (newest first). Access fields by attribute.
# facts[0].subject == "customer-4812"
# facts[0].predicate == "likes" # normalized; raw verb in predicate_raw
# facts[0].predicate_raw == "prefers"
# facts[0].object == "vegetarian meals"
# facts[0].invalid_at is None # still live (None == active)
# facts[1].predicate == "allergic_to", facts[1].object == "nuts"

When the staging tests pass, the only change is in the environment variable that holds the key. The same agent_id and user_id values that worked in staging work in production with no modification, and memories written by the staging key are invisible to the production key. A distinct agent_id such as support-bot-staging is optional; keep in mind that each distinct name holds one slot of the account-wide agent cap.


See also

  • The memory model, the three-layer architecture (managed store, session memory, cross-session facts) that sits underneath every key and project.
  • The knowledge graph, how entities and typed facts are extracted automatically from every add() call and why agent_id keeps graph namespaces clean.
  • API reference, full parameter docs for POST /v1/memories, GET /v1/facts, and the rest of the /v1 contract your agents call.