> For the complete documentation index, see [llms.txt](https://docs.kangal.dev/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.kangal.dev/tr/developer-portal/publishing-applications.md).

# API yayınlama ve application kaydı

Geliştirici Portalı, mevcut gateway servislerini ve route'larını bu kaynaklardaki etiket kuralı üzerinden yayımlar.

## Servis yayımlama

Aşağıdaki değerlerden biri doğru olduğunda servis herkese açık olur:

```
portal_visible: true
published: true
labels.portal_visible: true
labels.published: true
labels.portal: "public"
labels.portal: "published"
labels.portal: true
```

Admin Service API, yayın metadata'sını `labels` üzerinden sunar. `description`, `version`, `docs_url` ve `openapi_url` müşteri alanlarını da etiketlerden okur.

```bash
curl -sS -X PATCH \
  "$KANGAL_ADMIN_URL/admin/gateways/$GATEWAY_ID/services/$SERVICE_ID" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "labels": {
      "portal": "public",
      "description": "Create and inspect customer orders.",
      "version": "2026.2",
      "docs_url": "https://docs.example.com/orders",
      "openapi_url": "https://docs.example.com/orders/openapi.json",
      "portal_approval_required": true
    }
  }'
```

`PATCH`, `labels` nesnesinin tamamını değiştirir. Yayımlamadan önce mevcut etiketleri okuyun ve ilgisiz etiketleri yeni nesnede koruyun.

## Route yayımlama

Herkese açık bir servis, aynı portal etiketi kuralını bağımsız olarak karşılayan route'ları içerir. Route ayrıca servise `service_id` veya `service_name` ile başvurmalıdır.

```bash
curl -sS -X PATCH \
  "$KANGAL_ADMIN_URL/admin/gateways/$GATEWAY_ID/routes/$ROUTE_ID" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "labels": {
      "portal_visible": true,
      "summary": "List orders",
      "description": "Returns orders visible to the authenticated consumer."
    }
  }'
```

Katalog; route `path` değerini, büyük harfli `methods` değerlerini, `hosts`, `snis`, bağlı servis kimliklerini, özeti, açıklamayı ve etiketleri yayımlar.

Değişiklik günlüğü kayıtlarının yayını, servis ve route etiketlerinden bağımsız yönetilir. Bir servisi private yapmadan önce değişiklik günlüğü yönetim akışından tüm kayıtlarının `published` değerini `false` yapın; ardından servis ve route etiketlerini herkese açık olmayan değerlere değiştirin. API sürümlerini yalnızca ileri yönlü sürüm yaşam döngüsüyle emekliye ayırın; retirement ve katalog görünürlüğü ayrı işlemlerdir.

## Anonim görünürlüğü doğrulama

```bash
curl -sS \
  "$KANGAL_ADMIN_URL/portal/catalog?tenant_id=$TENANT_ID&gateway_id=$GATEWAY_ID"
```

Ardından bir servisi ve üretilmiş sözleşmesini doğrulayın:

```bash
curl -sS \
  "$KANGAL_ADMIN_URL/portal/services/$SERVICE_ID/openapi?tenant_id=$TENANT_ID&gateway_id=$GATEWAY_ID"
```

Yönetici önizlemesi için `include_unpublished=true` parametresini ve kimliği doğrulanmış, okuma yetkili yönetici kullanıcının Kangal oturumuna ait Bearer JWT'sini ekleyin. Admin API token'ı portal önizleme kimlik bilgisi değildir; anonim önizleme isteği `403` döndürür.

Bir servisi yayımlarken veya private yaparken katalog, servis, OpenAPI, değişiklik günlüğü ve sürüm endpoint'lerinin anonim yanıtlarını doğrulayın. Özellikle servis ve route etiketlerini private yapmadan önce servisin anonim değişiklik günlüğünün boş olduğunu kontrol edin.

## Üretilmiş OpenAPI içeriği

OpenAPI endpoint'i, güncel yayımlanmış route envanterinden `3.0.3` sürümünde belge üretir:

* servis adı, açıklaması ve sürümü `info` alanına dönüşür;
* her route path'i ve metodu bir operation oluşturur;
* route özeti ve açıklaması kopyalanır;
* genel `200`, `400`, `401` ve `500` yanıtları eklenir.

`openapi_url`, harici dokümantasyon bağlantısı olarak saklanır. Client üretimi veya sözleşme testi öncesinde endpoint'in ürettiği JSON belgesini inceleyin.

## API sürümlerini yönetme

Bir taslak oluşturun:

```bash
curl -sS -X POST \
  "$KANGAL_ADMIN_URL/portal/services/$SERVICE_ID/versions?tenant_id=$TENANT_ID&gateway_id=$GATEWAY_ID" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "version": "2026.2",
    "lifecycle": "draft",
    "release_notes": "Adds bulk order lookup.",
    "specification_url": "https://docs.example.com/orders/2026.2/openapi.json"
  }'
```

`version` 1-80 karakterdir ve tenant, gateway, servis ile değer kapsamında benzersizdir. `release_notes` en fazla 5.000, `specification_url` en fazla 500 karakter olabilir. Sürüm oluşturulurken route'lardan türetilen değiştirilemez OpenAPI snapshot'ı saklanır. `specification_url` harici belge bağlantısıdır; SDK üretiminde saklanan snapshot kullanılır.

Yaşam döngüsü yalnızca ileri yönde ilerler:

```
draft -> published -> deprecated -> retired
```

Aynı duruma geçiş, metadata güncellemeleri için kullanılabilir. Durum atlamak veya geriye dönmek `409` döndürür. Kullanım dışına alma işlemi boş olmayan bir `deprecation_notice` gerektirir; alan en fazla 2.000 karakter olabilir ve `sunset_at` eklenebilir. Herkese açık sürüm listeleri `published` ve `deprecated` durumlarını gösterir; `draft` ve `retired` durumları yönetici önizlemesinde görüntülenir.

```bash
curl -sS -X PATCH \
  "$KANGAL_ADMIN_URL/portal/services/$SERVICE_ID/versions/$VERSION_ID?tenant_id=$TENANT_ID&gateway_id=$GATEWAY_ID" \
  -H "Authorization: Bearer $ADMIN_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "lifecycle": "deprecated",
    "deprecation_notice": "Move to 2027.1 before sunset.",
    "sunset_at": "2027-06-30T21:00:00Z"
  }'
```

Kullanım dışına alınmış bir sürüm açıkça `retired` durumuna geçirilene kadar herkese açık sürüm listesinde kalır; `sunset_at` zamanına ulaşmak sürümü gizlemez veya yaşam döngüsünü değiştirmez. Sunset zamanında Kangal bu sürüm için yeni abonelikleri ve kimlik bilgisi üretimini engeller. Sürümü herkese açık listeden kaldırmak için `PATCH` yaşam döngüsü akışıyla `retired` durumuna geçirin; retirement ayrıca bağlı uygulamaları `suspended_api_version` durumuna getirir ve kimlik bilgilerinin süresini hemen sona erdirir.

## Değişiklik günlüğü kaydı yayımlama

`POST /portal/services/{service_id}/changelog` şu alanları kabul eder:

| Alan          | Kurallar                                                             |
| ------------- | -------------------------------------------------------------------- |
| `title`       | Zorunlu, 1-200 karakter                                              |
| `body`        | İsteğe bağlı, en fazla 5.000 karakter                                |
| `version`     | İsteğe bağlı, en fazla 80 karakter                                   |
| `change_type` | `added`, `changed`, `deprecated`, `removed`, `fixed` veya `security` |
| `published`   | Varsayılan `true`; false kayıtlar yönetici önizlemesi gerektirir     |
| `metadata`    | Serbest JSON nesnesi                                                 |

Değişiklik günlüğü kayıtları en yeniden en eskiye sıralanır. `published` değeri, servis ve route yayın etiketlerinden bağımsız değerlendirilir. Bir servisi private yapmadan önce değişiklik günlüğü kayıtlarını yayından kaldırın ve anonim değişiklik günlüğü endpoint'ini doğrulayın.

## Uygulama başvuru alanları

Oturum açmış geliştiriciler şu endpoint'i çağırır:

```
POST /portal/services/{service_id}/applications?tenant_id=...&gateway_id=...
```

| Alan               | Kurallar                                           |
| ------------------ | -------------------------------------------------- |
| `app_name`         | Zorunlu, 1-120 karakter                            |
| `developer_email`  | Zorunlu, geçerli e-posta adresi                    |
| `developer_name`   | İsteğe bağlı, en fazla 120 karakter                |
| `description`      | İsteğe bağlı, en fazla 500 karakter                |
| `requested_scopes` | String listesi; boş değerler kaldırılır            |
| `ttl_seconds`      | İsteğe bağlı pozitif tamsayı                       |
| `api_version`      | İsteğe bağlı sürüm adı veya kimliği, 1-80 karakter |
| `labels`           | Serbest JSON nesnesi                               |

Sürüm kayıtları varsa istek, yayımlanmış veya `sunset_at` zamanı gelmemiş kullanım dışı bir sürümle eşleşmelidir. `api_version` verilmezse Kangal önce en yeni yayımlanmış sürümü, ardından en yeni uyumlu kullanım dışı sürümü seçer. Sürüm kaydı bulunmayan servislerde sürümsüz uygulama oluşturulabilir.

Herkese açık portaldan yapılan istekler 24 saatlik anahtar ömrü ve standart örnek scope'lar kullanır. Gateway yönetici portalındaki form varsayılan olarak 30 gün kullanır ve virgülle ayrılmış scope listesi kabul eder. API istemcileri yukarıdaki tablodaki alanları gönderebilir.

## Otomatik ve manuel onay

`approval_required` veya `portal_approval_required` servis alanı/etiketlerinden biri doğruysa ya da `labels.portal_approval` değeri `required`, `manual` veya `true` ise manuel onay etkinleşir.

Bu etiket olmadığında:

1. Kangal, tenant kapsamındaki `developer-portal` consumer'ını oluşturur veya yeniden kullanır.
2. `mgk_` ile başlayan ve depolama sırasında şifrelenen bir `api_key` üretir.
3. Uygulama, yeni üretilen anahtarla birlikte `active` durumunda döner. Oluşturma yanıtındaki anahtarı alın ve onaylı bir secret store içinde saklayın.

Manuel onayda:

1. Kayıt, kimlik bilgisi olmadan `pending_approval` durumunda döner.
2. Tenant yöneticileri bekleyen istekleri `GET /portal/applications?tenant_id=...&gateway_id=...&status=pending_approval` ile listeler.
3. Onay işlemi kimlik bilgisini üretir. Başarılı onay yanıtındaki anahtarı alın ve onaylı bir secret store içinde saklayın; ret işlemi inceleyen kişiyi, zamanı ve isteğe bağlı nedeni kaydeder.
4. Onayın tekrarlanması idempotent'tır.

Kimliği doğrulanmış başvuru sahibi farklı bir tenant'ta bulunabilir. Üretilen consumer ve kimlik bilgisi, yayımlanmış API'nin çalışma zamanı kapsamı olan API yayıncısı tenant'a aittir.

## Sorun giderme

| Durum veya belirti                     | Kontrol                                                                                                                |
| -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------- |
| Yayımlanmış serviste route görünmüyor  | Her route'un kendi herkese açık etiketi ve eşleşen servis referansı olmalıdır                                          |
| Katalogda beklenmeyen servis görünüyor | Kapsamdaki tüm servis ve route'lara açık veya özel etiket verip anonim kataloğu yeniden doğrulayın                     |
| Önizlemede `403`                       | İstenen tenant için okuma yetkili yönetici kullanıcının Kangal oturum JWT'sini kullanın; Admin API token'ı kullanmayın |
| Kayıtta `401`                          | JWT'yi ve Redis destekli kullanıcı oturumunun geçerliliğini kontrol edin                                               |
| `404 Portal service not found`         | Tenant/gateway/servis kimliklerini, yayın etiketini ve route kapsamını kontrol edin                                    |
| `409 API version ... already exists`   | Sürüm değeri servis kapsamında benzersiz olmalıdır                                                                     |
| `409 No published API version`         | Kayıttan önce taslağı yayımlayın veya uyumlu bir sürüm seçin                                                           |
| Uygulama beklemede kalıyor             | Servis manuel onay gerektiriyorsa yönetici portalından veya API'den onaylayın                                          |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.kangal.dev/tr/developer-portal/publishing-applications.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
