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; agent_id and user_id scope data within the key.

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.
  • 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.

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 / key scope 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 today

In this first milestone a project organizes your keys and dashboard views. It groups keys, gives you a place to read usage per project, and lets you promote a key from staging to production.

Memories and facts are account-wide today. A staging key and a production key in two different projects see the same memory. A project does not yet wall off the data its keys read and write. Full per-project memory isolation is coming — until it lands, do not rely on a project to keep staging writes out of production reads.

Quotas are account-wide too. Staging and production share one write pool and one read pool; there is no per-project budget yet. Per-project quotas are a future option, not a guarantee today.

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 — once full per-project isolation ships. 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. Today that gives you separate keys, usage views, and the staging → production promotion path; the memory wall between them is the part that is still coming.

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. Once full per-project memory isolation ships, memories written by the staging key will be invisible to the production key; today both keys share the same account-wide memory store, so use a distinct agent_id prefix (such as support-bot-staging vs support-bot) as a lightweight namespace until the wall is in place.


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.