Add business-level outcome guidance to API Design Guide#578
Conversation
Rename Chapter 3 from "Error Responses" to "Responses" and add new section 3.1 with normative guidance for modeling business-level outcomes in successful (2xx) responses. This addresses inconsistent patterns across CAMARA APIs for representing negative, partial, or unknown business outcomes. Key additions: - Core principles using RFC 2119 keywords - Recommended pattern: primary outcome field + optional reason/message - OpenAPI and JSON examples - Versioning and migration guidance Fixes camaraproject#555
Replace the API-specific tenure/ported-number example with a generic privacy restriction scenario. The previous example had two issues: - It was tied to a specific API (Tenure) without verification - The detailed reason could reveal more information than necessary about the requested phone number The new example (REGIONAL_PRIVACY_RESTRICTION) is intentionally generic and better illustrates why the optional reason field adds value beyond the primary outcome alone.
| "outcomeMessage": "The requested information could not be disclosed for privacy regulation reasons." | ||
| } | ||
| ``` | ||
|
|
There was a problem hiding this comment.
I like this, my only suggestion is that we can inform the API Consumer if the outcome is temporary (that's not the case in this example, but there may be other cases). The addition of an optional 'retryAfter' field with a time metric would indicate that the outcome may change following a subsequent attempt.
|
Fully agree to proposed solution from Aduna perspective. It would be even better if CAMARA could recommend the name of the primary outcome field, e.g. "result". |
| * APIs **MAY** add optional refinement fields derived from the primary outcome field name, such as: | ||
| * a machine-readable `<baseName>Reason` (typed enum), and | ||
| * a human-readable `<baseName>Message` (free-text string). | ||
| * HTTP `4xx` status codes **MUST** be reserved for true request errors (invalid input, unsupported identifier, authentication/authorization failure, or contract/configuration mismatches). |
There was a problem hiding this comment.
In this section, is being considered 422 - SERVICE_NOT_APPLICABLE exception as well?
There was a problem hiding this comment.
Even we foresee that within API Initiatives will be specific discussion about some 422 scenarios to be covered by 200 cases (not all will be black or white).
We think that are scenarios for 422 - SERVICE_NOT_APPLICABLE (or other ones, in case they are not dependant on "mutable/temporal request conditions" (i.e. service exceptions)) that has to be kept.
Some examples below:
- Scam Signal:
422 - SERVICE_NOT_APPLICABLE. Background: Issue Proposal to add error response for not supported method for phone number #138. For instance, when API provider does not support a specific identifier (due to it belongs to non-supported segment, this is applicable to many APIs) - Sim Swap:
422 - SERVICE_NOT_APPLICABLE. - Location Verification:
422 - SERVICE_NOT_APPLICABLE
There was a problem hiding this comment.
Another 422 case (different than 422 - SERVICE_NOT_APPLICABLE):
Location Verification: 422 LOCATION_VERIFICATION.AREA_NOT_COVERED because it can be considered that the service cannot be delivered for such an area.
There was a problem hiding this comment.
@PedroDiez please see my comment #578 (comment) below
|
|
||
| * HTTP `2xx` responses indicate that the request was valid and processed; they **MAY** still represent negative, partial, or unknown business outcomes. | ||
| * Business-level outcomes **SHOULD** be modeled explicitly in the response body rather than inferred from missing data or encoded as errors. | ||
| * APIs that can yield multiple business outcomes **SHOULD** expose a mandatory, typed primary outcome field (for example `status`, `verificationResult`, `availability`, or `responseStatus`) defined as an enum or closed set of values. |
There was a problem hiding this comment.
Think we should specify a common name. That will be benefit for:
- Avoid name divergences when evaluating this outcome within an API initiative
- Ease automation checks or verifications performed in the future
There was a problem hiding this comment.
@PedroDiez see my comment #578 (comment) below
| * HTTP `2xx` responses indicate that the request was valid and processed; they **MAY** still represent negative, partial, or unknown business outcomes. | ||
| * Business-level outcomes **SHOULD** be modeled explicitly in the response body rather than inferred from missing data or encoded as errors. | ||
| * APIs that can yield multiple business outcomes **SHOULD** expose a mandatory, typed primary outcome field (for example `status`, `verificationResult`, `availability`, or `responseStatus`) defined as an enum or closed set of values. | ||
| * APIs **MAY** add optional refinement fields derived from the primary outcome field name, such as: |
There was a problem hiding this comment.
That is a good approach, to have additional user-friendly and machine-friendly. Think we should agree in concrete names for the same reason as above comment.
There was a problem hiding this comment.
The names are defined as <baseName>, <baseName>Reason, <baseName>Message - just that the <baseName> is domain specific. See my comment below for the rational.
|
|
||
| The recommended structural pattern for business-level outcomes consists of: | ||
|
|
||
| * A **mandatory primary outcome field** representing the business result (for example `status`, `verificationResult`, or `outcome`). |
There was a problem hiding this comment.
Think we should agree on a common name and define a structure, to specify a common guideline and avoid divergences among API initiatives
There was a problem hiding this comment.
See my comment below regarding a common name. Having the proposed pattern as a guideline will IMHO immediately help to reduce divergences which we have today in CAMARA for the reason that there wasn't such guideline.
|
@PedroDiez @Elisabeth-Mueller @gmuratk @shilpa-padgaonkar Let me explain why I have chosen to propose domain API specific primary outcome fields:
We can revisit a reusable schema later once the pattern is proven and stable across several APIs. Also can Sub Projects agree in their domains on a common primary outcome field. |
|
I agree that @PedroDiez comments highlight a real challenge we already see across CAMARA APIs. In practice, several APIs have used This PR does not try to reclassify or invalidate existing I think the right way forward is to explicitly acknowledge that:
Trying to fully resolve that classification problem in this PR would significantly increase its scope. Establishing the business-outcome pattern first gives us a solid foundation to address the |
|
Thanks @hdamker . Fully agree to start with the scope of establishing the business outcome pattern first and as next step address the 2xx vs 422 tension. |
| type: string | ||
| description: Business-level result of the operation. | ||
| enum: | ||
| - SUCCESS |
There was a problem hiding this comment.
I don't think we need to change anything in this enum, but thought this was worth pointing out:
Note that 'SUCCESS" here is the API provider's view of the outcome - which may not be the same as the API Consumer's view.
For example: the API Provider believes it has accurately fulfilled a location-verification request - but the information turns out to be inaccurate. In this case, the API provider states Business-level 'SUCCESS', even though the API Consumer has been given inaccurate information. So the 'Business-level result' is not success in this case.
So: 'SUCCESS' in the Business-level outcome schema should be understood as meaning "from the API Providers perspective", which is worth capturing in the API Design Guide.
| type: string | ||
| description: Optional human-readable explanation of the outcome. | ||
| example: "The requested information could not be disclosed for privacy regulation reasons." | ||
| ``` |
There was a problem hiding this comment.
| ``` | |
| retryAfter: | |
| type: string | |
| format: duration | |
| description: Optional indication that the outcome may be temporary, and that a different outcome may result if the request is repeated after the RFC 3339 duration indicated. | |
| example: "P0DT1H30M" |
There was a problem hiding this comment.
^ I'm aware that retryAfter would not be suitable for the rest of the example (a regional privacy restriction), but generally I believe it's worth including as an option for cases where the initial outcome may be temporary.
There was a problem hiding this comment.
In principle, I like the idea. It makes sense as an optional refinement of the business-outcome pattern, similar to …Reason or …Message, rather than something mandatory. Many outcomes are not retryable, and providers may not always be able to reliably predict when a retry would succeed.
If we include such a field, it should be:
- strictly OPTIONAL,
- clearly documented as a hint, not a guarantee,
- and scoped to cases where the provider has reasonable confidence that a retry may lead to a different outcome.
Using an RFC 3339 duration is fine, and placing it next to the outcome message also makes sense. We just need to be careful not to blur this with HTTP-level Retry-After semantics or make it part of the core outcome model.
That said, incorporating this properly would require additional text, clearer semantics, and possibly further examples, which would extend the scope of this PR. My suggestion would be to merge the current guidance first and, if there is broader support for this extension, follow up with a separate issue and PR to discuss and specify this retry-related aspect in more detail.
Align with existing document style where MUST, SHOULD, MAY keywords are capitalized but not bold.
@hdamker @PedroDiez
With common standardized names it would be more intuitive to define some cross-API common reason codes like:
Other codes can be of course added in API specifcations and even in provider implementations. |
|
Hi @rartych Your proposal sounds good to me. |
| ## 3. Error Responses | ||
| ## 3. Responses | ||
|
|
||
| This chapter covers how CAMARA APIs model responses, including both successful business outcomes and error conditions. |
There was a problem hiding this comment.
I think, I understand the intentions behind this text suggestion. However, it is very difficult to understand without the text in the PR front page.
Some thinking:
- Would be good to add a definition or a description of 'successful business outcome', incl giving some examples.
- Is this only about successful business outcome or about general general business outcome.
- Do all 2xx type HTTP status codes contain some "successful business outcome", incl 202, 204? Or is this "business outcome" an additional piece of information, which only some of the HTTP 2xx status codes provide?
There was a problem hiding this comment.
add a definition or a description of 'successful business outcome'
Per my earlier comment , the API Consumer may have a different perspective of 'successful business outcome' than the API Provider - certainly at the point the response was fulfilled. It may not be until later reconciliation that any difference between the two viewpoints becomes apparent. So the definition/description should account for that, or rename 'business outcome' as 'API fulfilment'.
There was a problem hiding this comment.
Yes, there are relations and this is another consequence of the missing description / definition.
Readers of the API Design Guideline need to understand the purpose of the feature in order to model good parameters and values.
|
|
||
| This chapter covers how CAMARA APIs model responses, including both successful business outcomes and error conditions. | ||
|
|
||
| ### 3.1. Business-level Outcomes in Successful Responses |
There was a problem hiding this comment.
On the name "Successful Responses": Is this about a 2xx HTTP Status Code or about a "successfully delivered response", i.e. any HTTP status code?"
|
|
||
| The following principles apply to modeling business-level outcomes in successful responses: | ||
|
|
||
| * HTTP `2xx` responses indicate that the request was valid and processed; they MAY still represent negative, partial, or unknown business outcomes. |
There was a problem hiding this comment.
| * HTTP `2xx` responses indicate that the request was valid and processed; they MAY still represent negative, partial, or unknown business outcomes. | |
| * HTTP `2xx` status codes indicate that the request was valid and processed; they MAY still represent negative, partial, or unknown business outcomes. | |
I am assuming, that Commonalities use the HTTP terminology, i.e. separate between HTTP responses (the complete response with headers and body) and the HTTP status codes.
| * APIs MAY add optional refinement fields derived from the primary outcome field name, such as: | ||
| * a machine-readable `<baseName>Reason` (typed enum), and | ||
| * a human-readable `<baseName>Message` (free-text string). | ||
| * HTTP `4xx` status codes MUST be reserved for true request errors (invalid input, unsupported identifier, authentication/authorization failure, or contract/configuration mismatches). |
There was a problem hiding this comment.
Is the consequence that 4xx status codes CANNOT convey any business outcome information? When yes, it should be made clear here to the reader.
| The following principles apply to modeling business-level outcomes in successful responses: | ||
|
|
||
| * HTTP `2xx` responses indicate that the request was valid and processed; they MAY still represent negative, partial, or unknown business outcomes. | ||
| * Business-level outcomes SHOULD be modeled explicitly in the response body rather than inferred from missing data or encoded as errors. |
There was a problem hiding this comment.
| * Business-level outcomes SHOULD be modeled explicitly in the response body rather than inferred from missing data or encoded as errors. | |
| * Business-level outcomes MUST be modeled explicitly in the response body rather than inferred from missing data or encoded as errors. | |
Consistency with line 251 ("A mandatory primary outcome field representing...").
Or, did I miss interpret the meaning of "mandatory" of the primary field?
| example: "The requested information could not be disclosed for privacy regulation reasons." | ||
| ``` | ||
|
|
||
| An example JSON response using HTTP `200`: |
There was a problem hiding this comment.
| An example JSON response using HTTP `200`: | |
| An example JSON formatted HTTP response body (e.g. body of an HTTP response with a `200` status code): |
Hi, Thanks for the comments and clarifications about your view Herbert. I still think naming convention for the primary outcome field and optional user-friendly and machine-friendly fields is the "mininum" with have to agree on. In that way, we willl be all aligned in the use of this approach among API initiatives understanding the scope of whatever is going to be behind it, and set-up the basis for a latter automation. @rartych has made some proposal for the optional fields (contextCode / contextMessage). For the primary outcome field i would propose I understand that trying to think about a common structure for the primary outcome field can be ambitious, even not the more appropiated strategy due to differences in APIs nature and design. It is completely reasonable to check this point after applying these model across different inititatives and look for "a feasible common approach/synergies".
This is reasonable. To me most important point is that we all understand we have to do an analysis of this in order to minimize future discussions in API initiatives. I will open a new Issue in order to address this discussion (200 case vs 422 cases) and reach some conclusions |
|
Just to summarize our view, We are happy to move forward with this PR with these approach:
|
|
|
||
| * HTTP `2xx` responses indicate that the request was valid and processed; they MAY still represent negative, partial, or unknown business outcomes. | ||
| * Business-level outcomes SHOULD be modeled explicitly in the response body rather than inferred from missing data or encoded as errors. | ||
| * APIs that can yield multiple business outcomes SHOULD expose a mandatory, typed primary outcome field (for example `status`, `verificationResult`, `availability`, or `responseStatus`) defined as an enum or closed set of values. |
There was a problem hiding this comment.
One point that is somehow still not clear to me is about the coliving of this outcome information with a "regular successful" API response. I mean, when returning this information, "regular" API response is not return at all? so they are mutually exclusive?
|
To be sure to get the proposal with an example. |
|
As a developer, I don't appreciate 2XX responses that don't provide the information the user expects. This type of response complicates the experience for API users (especially those using strongly typed languages like Java, Kotlin, Rust, or Go, for example). |
|
@PedroDiez, all: I'm working currently on a refinement of the PR together with @gmuratk. Please wait with further comments for the update. |
…context fields This commit refines the guidance in Chapter 3.1 to better reflect existing CAMARA API practices and provide clearer design direction. Key updates: - Reframe the guidance around legitimate existing patterns for modeling negative, partial, or unknown business outcomes in HTTP 2xx responses - Present explicit outcome enums and documented nullability/presence rules as equally valid approaches - Introduce optional, standardized `contextCode` and `contextMessage` fields as additive refinements, not replacements for outcome semantics - Clarify client interpretation: context fields are supplementary and must not be the sole basis for determining the business outcome - Refine 2xx vs 4xx guidance to emphasize that improved outcome modeling in 2xx responses can reduce the need for 4xx responses on valid requests - Consolidate and simplify the Core Principles section for clarity The guidance applies primarily to new APIs and new MAJOR versions; existing APIs may evolve towards it over time.
|
Important note to reviewers – proposal refined @PedroDiez @Kevsy @Elisabeth-Mueller @gmuratk @shilpa-padgaonkar @bigludo7 @patrice-conil @tlohmar @rartych I’ve pushed a squash commit that significantly refines the proposal in this PR in 63fb51d Based on the discussion in this PR, #555, and follow-up feedback (including offline discussions), I reframed the guidance in Section 3.1. In particular, the proposal is no longer about introducing a mandatory new “primary outcome” field or a single preferred modeling approach. The updated guidance:
Given this pivot, I’d appreciate reviewers to re-evaluate the PR based on the current state of the text, rather than earlier iterations or the original proposal description. Feedback on the revised direction is very welcome. |
|
@hdamker ,
I can suggest edits, but I wanted to share the overall feedback and see if you, and team, agree first. |
| * `contextMessage` — a human-readable explanation providing additional context | ||
| * These optional context fields are additive and MUST NOT be the only way to interpret the business outcome of a successful response. | ||
| * Outcome semantics (success, failure, partial, unknown, not applicable) MUST remain visible via the API's domain-specific response semantics and MUST NOT be moved into `contextCode` or `contextMessage`. | ||
| * HTTP `4xx` status codes SHOULD be reserved for true request errors (invalid input, unsupported identifier, authentication/authorization failure, or contract/configuration mismatches). |
There was a problem hiding this comment.
I've still probably issue for this one when the request the valid but the server is not able to serve it.
This is the case in Device location Family. Take Location Verification, if the MNO is not able to locate for any reason a supposed locate-able device we send a 422 unable to locate. For the WG we moved from 200 (with "verificationResult": "UNKNOWN") to this 422 to be way more explicit and easy to understand (and charge btw)
Let le know Herbert if i miss something in your proposal.
cc @jlurien
There was a problem hiding this comment.
It is fair point @bigludo7 .
But having business outcome defined i.e. the 200 response covering limited success we can make CAMARA APIs more consistent.
In Location Verification we have:
If the location information known to the server is older than the specified
maxAgeor not known at all, an error with code422 LOCATION_VERIFICATION.UNABLE_TO_FULFILL_MAX_AGEis sent back,
but in device Roaming Status we can have 200 response with:
LastStatusTime : The time when the status was last confirmed to be correct. An older status is more likely to now be incorrect.
So for the same device (switched-off for some time) we currently can get different kinds of responses (200 and 422).
Proposed approach leads to more common understanding of such cases.
There was a problem hiding this comment.
@bigludo7 the guidance is not meant to solve the topic 2xx vs 4xxx finally ... there need always to be domain specific discussions. But describing how a limited business outcome may be expressed as a 2xx outcome allows a balanced discussion within the API domains, and probably will avoid cases where a correct and valid API request will be answered by an error (which always requires extra handling for the API client, even if the client cannot change anything about it). Regarding "easier to charge" ... there are pros and cons for provider and consumer -- we might need to think about the consumer (aka customer) first.
There was a problem hiding this comment.
This is one example about my concern among 2xx vs 4xx. Just to avoid so much discussions within API initiatives. I am thinking about some refinements, over the background of the PR:
- Point is not define a primary outcome structure, as several approaches may work (enhance some field values,
oneOfsolution, definition of the model from scratch, API re-desing and that is internal to API Initiative,...). - It is important that API behaviour (i.e implementation) is the same for any API provider for the same scenario, otherwise interoperability will not be guaranteed.
There was a problem hiding this comment.
- It is important that API behaviour (i.e implementation) is the same for any API provider for the same scenario, otherwise interoperability will not be guaranteed.
Agree especially on this point. Not necessarily the implementation but the response.
Will you propose these refinements?
There was a problem hiding this comment.
Hi Herbert, yes. Let me today for providing them
There was a problem hiding this comment.
@bigludo7 the guidance is not meant to solve the topic 2xx vs 4xxx finally ... there need always to be domain specific discussions. But describing how a limited business outcome may be expressed as a 2xx outcome allows a balanced discussion within the API domains, and probably will avoid cases where a correct and valid API request will be answered by an error (which always requires extra handling for the API client, even if the client cannot change anything about it). Regarding "easier to charge" ... there are pros and cons for provider and consumer -- we might need to think about the consumer (aka customer) first.
Even though the goal isn't to resolve the 2xx vs. 4xx issue, line 245 clearly favors 2xx and will require modifications to APIs that have opted for 4xx in future major versions. If this leads to greater consistency, why not, but care must be taken not to overcomplicate the work of API consumers.
There was a problem hiding this comment.
@patrice-conil @bigludo7 I see the point that the introduction of this guidance should be neutral regarding 2xx vs 4xx use and have therefore removed the point in former line 245 (see 766deff).
| The following principles apply to modeling business-level outcomes in successful responses: | ||
|
|
||
| * HTTP `2xx` status codes indicate that the request was valid and processed; they MAY still represent negative, partial, or unknown business outcomes. | ||
| * APIs SHOULD explicitly define and document how business outcomes are represented in successful responses (for example via explicit outcome enums, documented nullability, or documented presence/absence rules), and MUST NOT rely on undocumented inference from missing data. |
There was a problem hiding this comment.
Line 239: provide clear guidance about behaviour, avoiding different behaviour in the same business scenario
| * APIs SHOULD explicitly define and document how business outcomes are represented in successful responses (for example via explicit outcome enums, documented nullability, or documented presence/absence rules), and MUST NOT rely on undocumented inference from missing data. | |
| * APIs SHOULD explicitly define and document how business outcomes are represented in successful responses (for example via explicit outcome enums, documented nullability, or documented presence/absence rules), and MUST NOT rely on undocumented inference from missing data. They SHOULD also explicitly define the behavior of the different business scenarios to ensure consistent behavior in each case (i.e. identifiy a clear separation among 2xx vs 4xx). |
There was a problem hiding this comment.
I propose that this guidance should be given in a separate section of the chapter, e.g. after 3.2.
See also my next comment that we agreed that we can't solve this topic here in the PR (and in the given time). The PR is only introducing the guidance for how to express 2xx limited outcomes, not when to use it.
| * `contextMessage` — a human-readable explanation providing additional context | ||
| * These optional context fields are additive and MUST NOT be the only way to interpret the business outcome of a successful response. | ||
| * Outcome semantics (success, failure, partial, unknown, not applicable) MUST remain visible via the API's domain-specific response semantics and MUST NOT be moved into `contextCode` or `contextMessage`. | ||
| * HTTP `4xx` status codes SHOULD be reserved for true request errors (invalid input, unsupported identifier, authentication/authorization failure, or contract/configuration mismatches). |
There was a problem hiding this comment.
Provide a new bullet below Line 245, to enforce the idea of ensuring the use of 2xx responses are not used to hide situations where the service cannot really being delivered and the user can be potentially being charged for it.
Something like:
"* Analysis of the outcome MUST evaluate the following condition: Not Applicable /Contractual: Service is not available for type of subscription, segment, config, etc. This is not a partial output as response does not vary in time. This ensures that the API behaviour does not allow performing billing normalization where there is no way to deliver the service "
There was a problem hiding this comment.
Ok, understood. Yes I will open an issue for that.
|
Within 98b99e8 I have as promised on Monday updated the existing example for a result enum as outcome and added an example for a nullable primary outcome. Hope that clarifies that both pattern are legitimate for 2xx results. |
|
Thanks a lot for your thorough review and detailed comments.
I wouldn't change the field names (for brevity, but also as the team mentioned that there could be other reasons for limited outcomes). We could mention business context within lines 241-242, change from to: What do you and others here think?
The PR leaves the values intentionally open for now and mentions only examples. But I'm skeptical about
The revision should avoid the suggestion that there must be a specific "primary outcome" field, but still I want to state that the outcome, including limited, must be visible for the client without looking into the
I'm here more with @PedroDiez and others that we must avoid this situation, but we also agreed that the actual discussion in which scenario the one or other should be used can't be solved in this PR.
The intention of 3.1.3 is exactly that: both patterns, also the nullable outcome field, are legitimate patterns. Within 98b99e8 I have removed the "explicit" word and added in 3.1.4 a second example with a nullable data field. Does that clarifies it?
That would make the
I have change the example to a proper
|
…ve-business-outcomes
What type of PR is this?
What this PR does / why we need it
This PR updates the CAMARA API Design Guide by refining Chapter 3 (“Responses”) and adding Section 3.1 – Business-level Outcomes in Successful Responses.
CAMARA APIs already return negative, partial, or unknown business outcomes under HTTP 2xx, but model these situations in different legitimate ways (explicit enums, nullability/presence rules, or sometimes 4xx usage). The lack of shared guidance leads to inconsistent API designs.
The proposed guidance:
contextCode,contextMessage) to provide additional machine- and human-readable context,No new schemas are introduced and no changes are mandated for existing APIs. The guidance is primarily intended for new APIs and new MAJOR versions.
Reviewers are encouraged to focus on the current text of Section 3.1, as the proposal has evolved during discussion.
Which issue(s) this PR fixes
Fixes #555
Does this PR introduce a breaking change?
This PR adds documentation guidance only. Individual APIs remain responsible for assessing breaking changes in their own versioning context.
Changelog input